Skip to content

Instantly share code, notes, and snippets.

@Stwissel
Last active December 20, 2023 22:10
Show Gist options
  • Save Stwissel/7855831098edb565b3da196f3ecb7bb1 to your computer and use it in GitHub Desktop.
Save Stwissel/7855831098edb565b3da196f3ecb7bb1 to your computer and use it in GitHub Desktop.
Transform a Salesforce WSDL into an OpenAPI 2.0 Swagger YAML file
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:w="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:enterprise.soap.sforce.com"
xmlns:fns="urn:fault.enterprise.soap.sforce.com"
xmlns:ens="urn:sobject.enterprise.soap.sforce.com"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text" encoding="UTF-8" indent="no" media-type="text/yaml"/>
<xsl:variable name="space2" select="' '"/>
<xsl:variable name="space4" select="' '"/>
<xsl:variable name="space6" select="' '"/>
<xsl:template match="/">
swagger: "2.0"
info:
description: "Sample implementation of a Salesfore SWAGGER File"
version: "1.0.0"
title: "Salesforce Rest API"
contact:
email: "swissel@salesforce.com"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: "login.salesforce.com"
basePath: "/services/data/v45.0"
schemes:
- "https"
paths:
<xsl:apply-templates select="/w:definitions/w:types/xsd:schema[@targetNamespace='urn:sobject.enterprise.soap.sforce.com']" mode="path"/>
definitions:
<xsl:apply-templates select="/w:definitions/w:types/xsd:schema"/>
# EOF
</xsl:template>
<xsl:template match="xsd:schema" >
<xsl:apply-templates select="xsd:complexType" />
</xsl:template>
<xsl:template match="xsd:complexType">
<xsl:value-of select="$space2"/><xsl:value-of select="@name"/>:
type: "object"
<xsl:if test="count(descendant::xsd:element) > 0"> properties:
<xsl:apply-templates select="descendant::xsd:element" />
</xsl:if>
<xsl:if test="count(descendant::xsd:element) = 0"> properties: {}
</xsl:if>
</xsl:template>
<xsl:template match="xsd:element">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
$ref: "#/definitions/<xsl:value-of select="replace(replace(@type,'tns:',''),'ens:','')"/>"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:anyType']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "object"
properties: {}
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:boolean']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "boolean"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:string']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "string"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:double']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "number"
format: "double"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:int']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "integer"
format: "int32"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:dateTime']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "string"
format: "date-time"
</xsl:template>
<xsl:template match="xsd:element[@type='xsd:date']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "string"
format: "date"
</xsl:template>
<xsl:template match="xsd:element[@type='tns:ID']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "string"
</xsl:template>
<xsl:template match="xsd:element[@type='ens:User']">
<xsl:value-of select="$space6"/><xsl:value-of select="@name"/>:
type: "string"
</xsl:template>
<xsl:template match="xsd:element" mode="required">
<xsl:value-of select="$space4"/>-<xsl:value-of select="@name"/>
</xsl:template>
<!-- Definition for a PATH -->
<xsl:template match="xsd:schema" mode="path" >
<xsl:apply-templates select="xsd:complexType" mode="path"/>
</xsl:template>
<xsl:template match="xsd:complexType" mode="path">
<xsl:value-of select="$space2"/>/services/data/v45.0/sobjects/<xsl:value-of select="@name"/>:
post:
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
required: true
schema:
$ref: "#/definitions/<xsl:value-of select="@name"/>"
responses:
405:
description: "Invalid input"
200:
description: "Success"
<xsl:value-of select="$space2"/>/services/data/v45.0/sobjects/<xsl:value-of select="@name"/>/{Id}:
get:
summary: "Find <xsl:value-of select="@name"/> by ID"
description: "Returns a single <xsl:value-of select="@name"/>"
produces:
- "application/json"
parameters:
- name: "Id"
in: "path"
description: "ID of <xsl:value-of select="@name"/> to return"
required: true
type: "string"
responses:
200:
description: "successful operation"
schema:
$ref: "#/definitions/<xsl:value-of select="@name"/>"
400:
description: "Invalid ID supplied"
404:
description: "<xsl:value-of select="@name"/> not found"
put:
summary: "Update <xsl:value-of select="@name"/>"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
required: true
schema:
$ref: "#/definitions/<xsl:value-of select="@name"/>"
responses:
400:
description: "Invalid operation"
200:
description: "Success"
</xsl:template>
<!-- Catch call to not render what we don't like -->
<xsl:template match="*" />
<!--
Unused stuff
<xsl:if test="count(descendant::xsd:element[nillable='false']) > 0">
required:
<xsl:apply-templates select="descendant::xsd:element[nillable='false']" mode="required"/>
</xsl:if>
-->
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment