3028 lines
129 KiB
HTML
3028 lines
129 KiB
HTML
<?xml version="1.0" encoding="utf-8"?>
|
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
|
|
xmlns:edm="http://docs.oasis-open.org/odata/ns/edm"
|
|
>
|
|
<!--
|
|
This style sheet transforms OData 4.0 XML CSDL documents into OpenAPI 2.0 JSON
|
|
|
|
Latest version: https://github.com/oasis-tcs/odata-openapi/tree/master/tools
|
|
|
|
TODO:
|
|
- Validation annotations -> pattern, minimum, maximum, exclusiveM??imum, see https://issues.oasis-open.org/browse/ODATA-856,
|
|
inline and explace style
|
|
- annotations within edm:UrlRef, with string value and expression value of edm:UrlRef
|
|
- complex or collection-valued function parameters need special treatment in /paths - use parameter aliases with alias
|
|
option of type string
|
|
- @Extends for entity container: include /paths from referenced container
|
|
- annotations without explicit value: default from term definition (if inline)
|
|
- links to referenced files relative to current Swagger UI?
|
|
- both "clickable" and freestyle $expand, $select, $orderby - does not work yet, open issue
|
|
- system query options for actions/functions/imports depending on "Collection("
|
|
- security/authentication
|
|
- 200 response for PATCH
|
|
- ETag / If-Match for PATCH
|
|
- property description for key parameters in single-entity requests - include @Common.Label or @Core.Description
|
|
- operation descriptions via predefined qualifiers: @Core.Description#GET, #POST, #PATCH (and/or #PUT), #DELETE on entity set,
|
|
singleton
|
|
- allow external targeting for @Core.Description similar to @Common.Label
|
|
- remove duplicated code in /paths production
|
|
- Capabilities: SortRestrictions/NonSortableProperties, FilterRestrictions/NonFilterableProperties
|
|
-->
|
|
|
|
<xsl:output method="text" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
|
|
<xsl:strip-space elements="*"/>
|
|
|
|
|
|
<xsl:param name="scheme" select="'http'"/>
|
|
<xsl:param name="host" select="'localhost'"/>
|
|
<xsl:param name="basePath" select="'/service-root'"/>
|
|
<xsl:param name="odata-schema" select="'https://raw.githubusercontent.com/ralfhandl/odata/master/edm.json'"/>
|
|
<xsl:param name="odata-version" select="'4.0'"/>
|
|
<xsl:param name="vocabulary-home" select="'http://localhost/examples'"/>
|
|
<xsl:param name="swagger-ui" select="'http://localhost/swagger-ui'"/>
|
|
<xsl:param name="diagram" select="null"/>
|
|
<xsl:param name="extensions" select="null"/>
|
|
<xsl:param name="openapi-formatoption" select="''"/>
|
|
|
|
|
|
<xsl:variable name="coreNamespace" select="'Org.OData.Core.V1'"/>
|
|
<xsl:variable name="coreAlias"
|
|
select="//edmx:Include[@Namespace=$coreNamespace]/@Alias|//edm:Schema[@Namespace=$coreNamespace]/@Alias"/>
|
|
<xsl:variable name="coreDescription" select="concat($coreNamespace,'.Description')"/>
|
|
<xsl:variable name="coreDescriptionAliased">
|
|
<xsl:choose>
|
|
<xsl:when test="$coreAlias">
|
|
<xsl:value-of select="concat($coreAlias,'.Description')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="'Core.Description'"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
|
|
<xsl:variable name="capabilitiesNamespace" select="'Org.OData.Capabilities.V1'"/>
|
|
<xsl:variable name="capabilitiesAlias"
|
|
select="//edmx:Include[@Namespace=$capabilitiesNamespace]/@Alias|//edm:Schema[@Namespace=$capabilitiesNamespace]/@Alias"/>
|
|
|
|
<xsl:variable name="commonNamespace" select="'com.sap.vocabularies.Common.v1'"/>
|
|
<xsl:variable name="commonAlias"
|
|
select="//edmx:Include[@Namespace=$commonNamespace]/@Alias|//edm:Schema[@Namespace=$commonNamespace]/@Alias"/>
|
|
<xsl:variable name="commonLabel" select="concat($commonNamespace,'.Label')"/>
|
|
<xsl:variable name="commonLabelAliased" select="concat($commonAlias,'.Label')"/>
|
|
|
|
<xsl:variable name="defaultResponse">
|
|
<xsl:text>"default":{"$ref":"#/responses/error"}</xsl:text>
|
|
</xsl:variable>
|
|
|
|
<xsl:key name="methods"
|
|
match="edmx:Edmx/edmx:DataServices/edm:Schema/edm:Action|edmx:Edmx/edmx:DataServices/edm:Schema/edm:Function"
|
|
use="concat(../@Namespace,'.',@Name)"/>
|
|
<xsl:key name="targets" match="edmx:Edmx/edmx:DataServices/edm:Schema/edm:Annotations"
|
|
use="concat(../@Namespace,'/',@Target)"/>
|
|
<xsl:key name="includeannotations" match="edmx:Edmx/edmx:Reference/edmx:IncludeAnnotations"
|
|
use="concat(../@Uri,'|',@TermNamespace)"/>
|
|
|
|
|
|
<xsl:template name="Core.Description">
|
|
<xsl:param name="node"/>
|
|
<xsl:variable name="description"
|
|
select="$node/edm:Annotation[(@Term=$coreDescription or @Term=$coreDescriptionAliased) and not(@Qualifier)]/@String|$node/edm:Annotation[(@Term=$coreDescription or @Term=$coreDescriptionAliased) and not(@Qualifier)]/edm:String"/>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="normalize-space($description)"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="Core-Annotation">
|
|
<xsl:param name="node"/>
|
|
<xsl:param name="term"/>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string"
|
|
select="$node/edm:Annotation[(@Term=concat('Org.OData.Core.V1.',$term) or @Term=concat($coreAlias,'.',$term)) and not(@Qualifier)]/@String|$node/edm:Annotation[(@Term=concat('Org.OData.Core.V1.',$term) or @Term=concat($coreAlias,'.',$term)) and not(@Qualifier)]/edm:String"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="Common.Label">
|
|
<xsl:param name="node"/>
|
|
<!-- TODO: consider explace annotations for properties -->
|
|
<xsl:variable name="label"
|
|
select="normalize-space($node/edm:Annotation[(@Term=$commonLabel or @Term=$commonLabelAliased) and not(@Qualifier)]/@String|$node/edm:Annotation[(@Term=$commonLabel or @Term=$commonLabelAliased) and not(@Qualifier)]/edm:String)"/>
|
|
|
|
<xsl:variable name="explaceLabel">
|
|
<xsl:choose>
|
|
<xsl:when test="local-name($node)='Property'">
|
|
<xsl:variable name="target" select="concat(../../@Alias,'.',../@Name,'/',@Name)"/>
|
|
<xsl:value-of
|
|
select="//edm:Annotations[@Target=$target and not(@Qualifier)]/edm:Annotation[@Term=(@Term=$commonLabel or @Term=$commonLabelAliased) and not(@Qualifier)]/@String"/>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<xsl:choose>
|
|
<xsl:when test="$label">
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="$label"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="$explaceLabel"/>
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="edmx:Edmx">
|
|
<!--
|
|
<xsl:message><xsl:value-of select="$commonAlias"/></xsl:message>
|
|
<xsl:message><xsl:value-of select="$commonNamespace"/></xsl:message>
|
|
-->
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:if test="$extensions">
|
|
<xsl:text>"x-odata-version":"</xsl:text>
|
|
<xsl:value-of select="$odata-version"/>
|
|
<xsl:text>",</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"swagger":"2.0"</xsl:text>
|
|
|
|
<xsl:text>,"info":{"title":"</xsl:text>
|
|
<xsl:variable name="title">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="//edm:Schema"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="containerTitle">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="//edm:EntityContainer"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="$title!=''">
|
|
<xsl:value-of select="$title"/>
|
|
</xsl:when>
|
|
<xsl:when test="$containerTitle!=''">
|
|
<xsl:value-of select="$containerTitle"/>
|
|
</xsl:when>
|
|
<xsl:when test="//edm:EntityContainer">
|
|
<xsl:text>OData Service for namespace </xsl:text>
|
|
<xsl:value-of select="//edm:EntityContainer/../@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>OData CSDL Document for namespace </xsl:text>
|
|
<xsl:value-of select="//edm:Schema/@Namespace"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<xsl:text>","version":"</xsl:text>
|
|
<xsl:variable name="version">
|
|
</xsl:variable>
|
|
<xsl:call-template name="Core-Annotation">
|
|
<xsl:with-param name="node" select="//edm:EntityContainer"/>
|
|
<xsl:with-param name="term" select="'SchemaVersion'"/>
|
|
</xsl:call-template>
|
|
|
|
<xsl:text>","description":"</xsl:text>
|
|
<xsl:variable name="description">
|
|
<xsl:call-template name="Core-Annotation">
|
|
<xsl:with-param name="node" select="//edm:Schema"/>
|
|
<xsl:with-param name="term" select="'LongDescription'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="containerDescription">
|
|
<xsl:call-template name="Core-Annotation">
|
|
<xsl:with-param name="node" select="//edm:EntityContainer"/>
|
|
<xsl:with-param name="term" select="'LongDescription'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="$description!=''">
|
|
<xsl:value-of select="$description"/>
|
|
</xsl:when>
|
|
<xsl:when test="$containerDescription!=''">
|
|
<xsl:value-of select="$containerDescription"/>
|
|
</xsl:when>
|
|
<xsl:when test="//edm:EntityContainer">
|
|
<xsl:text>This OData service is located at </xsl:text>
|
|
<xsl:value-of select="$scheme"/>
|
|
<xsl:text>://</xsl:text>
|
|
<xsl:value-of select="$host"/>
|
|
<xsl:value-of select="$basePath"/>
|
|
<xsl:text>/</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:if test="$diagram">
|
|
<xsl:apply-templates select="//edm:EntityType" mode="description"/>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="//edm:Term" mode="description"/>
|
|
<xsl:apply-templates select="//edmx:Include" mode="description"/>
|
|
<xsl:text>"}</xsl:text>
|
|
|
|
<xsl:if test="//edm:EntityContainer">
|
|
<xsl:text>,"schemes":["</xsl:text>
|
|
<xsl:value-of select="$scheme"/>
|
|
<xsl:text>"],"host":"</xsl:text>
|
|
<xsl:value-of select="$host"/>
|
|
<xsl:text>","basePath":"</xsl:text>
|
|
<xsl:value-of select="$basePath"/>
|
|
<xsl:text>"</xsl:text>
|
|
|
|
<!-- TODO: Capabilities.SupportedFormats -->
|
|
<xsl:text>,"consumes":["application/json"]</xsl:text>
|
|
<xsl:text>,"produces":["application/json"]</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="//edm:EntitySet|//edm:Singleton" mode="tags"/>
|
|
|
|
<xsl:apply-templates select="//edm:EntityType|//edm:ComplexType|//edm:TypeDefinition|//edm:EnumType"
|
|
mode="hash">
|
|
<xsl:with-param name="name" select="'definitions'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="//edm:Schema|edmx:Reference/edmx:Include" mode="hash">
|
|
<xsl:with-param name="key" select="'Namespace'"/>
|
|
<xsl:with-param name="name" select="'x-schemas'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:apply-templates
|
|
select="//edm:Action[generate-id() = generate-id(key('methods', concat(../@Namespace,'.',@Name))[1])]"
|
|
mode="hash"
|
|
>
|
|
<xsl:with-param name="name" select="'x-actions'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:apply-templates
|
|
select="//edm:Function[generate-id() = generate-id(key('methods', concat(../@Namespace,'.',@Name))[1])]"
|
|
mode="hash"
|
|
>
|
|
<xsl:with-param name="name" select="'x-functions'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:apply-templates select="//edm:Term" mode="hash">
|
|
<xsl:with-param name="name" select="'x-terms'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:apply-templates select="//edm:EntityContainer"/>
|
|
|
|
<xsl:apply-templates select="edmx:Reference[edmx:IncludeAnnotations|edm:Annotation]" mode="hash">
|
|
<xsl:with-param name="name" select="'x-references'"/>
|
|
<xsl:with-param name="key" select="'Uri'"/>
|
|
</xsl:apply-templates>
|
|
</xsl:if>
|
|
|
|
<!-- paths is required, so we need it also for documents that do not define an entity container -->
|
|
<xsl:text>,"paths":{</xsl:text>
|
|
<xsl:apply-templates select="//edm:EntityContainer" mode="paths"/>
|
|
<xsl:text>}</xsl:text>
|
|
|
|
<xsl:if test="//edm:EntityContainer">
|
|
<xsl:text>,"parameters":{</xsl:text>
|
|
<xsl:text>"top":{"name":"$top","in":"query","description":"Show only the first n items</xsl:text>
|
|
<xsl:text>, see [OData Paging - Top](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374630)","type":"integer"},</xsl:text>
|
|
<xsl:text>"skip":{"name":"$skip","in":"query","description":"Skip the first n items</xsl:text>
|
|
<xsl:text>, see [OData Paging - Skip](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374631)","type":"integer"},</xsl:text>
|
|
<xsl:text>"count":{"name":"$count","in":"query","description":"Include count of items</xsl:text>
|
|
<xsl:text>, see [OData Count](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374632)","type":"boolean"},</xsl:text>
|
|
<xsl:text>"filter":{"name":"$filter","in":"query","description":"Filter items by property values</xsl:text>
|
|
<xsl:text>, see [OData Filtering](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374625)","type":"string"},</xsl:text>
|
|
<xsl:text>"search":{"name":"$search","in":"query","description":"Search items by search phrases</xsl:text>
|
|
<xsl:text>, see [OData Searching](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374633)","type":"string"}}</xsl:text>
|
|
|
|
<xsl:text>,"responses":{"error":{"description":"Error","schema":{"$ref":"</xsl:text>
|
|
<xsl:value-of select="$odata-schema"/>
|
|
<xsl:text>#/definitions/odata.error"}}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntityType" mode="description">
|
|
<xsl:if test="position() = 1">
|
|
<xsl:text>\n\n## Entity Data Model\n![ER Diagram](http://yuml.me/diagram/class/</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="@BaseType" mode="description"/>
|
|
<xsl:text>[</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>]</xsl:text>
|
|
<xsl:apply-templates select="edm:NavigationProperty" mode="description"/>
|
|
<xsl:if test="position() = last()">
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@BaseType" mode="description">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="."/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="type">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="."/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:text>[</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$qualifier=../../@Namespace or $qualifier=../../@Alias">
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@Type"/>
|
|
<xsl:text>{bg:white}</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>]^</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:NavigationProperty" mode="description">
|
|
<xsl:variable name="singleType">
|
|
<xsl:choose>
|
|
<xsl:when test="starts-with(@Type,'Collection(')">
|
|
<xsl:value-of select="substring-before(substring-after(@Type,'('),')')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@Type"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="collection" select="starts-with(@Type,'Collection(')"/>
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$singleType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="type">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$singleType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="nullable">
|
|
<xsl:call-template name="nullableFacetValue">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<!--
|
|
TODO: evaluate Partner to just have one arrow
|
|
[FeaturedProduct]<0..1-0..1>[Advertisement]
|
|
-->
|
|
<xsl:text>,[</xsl:text>
|
|
<xsl:value-of select="../@Name"/>
|
|
<xsl:text>]-</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$collection">
|
|
<xsl:text>*</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$nullable">
|
|
<xsl:text>0..1</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:text>>[</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$qualifier=../../@Namespace or $qualifier=../../@Alias">
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$singleType"/>
|
|
<xsl:text>{bg:white}</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edmx:Include" mode="description">
|
|
<xsl:if test="position() = 1">
|
|
<xsl:text>\n\n## References</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>\n- [</xsl:text>
|
|
<xsl:value-of select="@Namespace"/>
|
|
<xsl:text>](</xsl:text>
|
|
<xsl:value-of select="$swagger-ui"/>
|
|
<xsl:text>/?url=</xsl:text>
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string">
|
|
<xsl:call-template name="json-url">
|
|
<xsl:with-param name="url" select="../@Uri"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
<xsl:with-param name="old" select="')'"/>
|
|
<xsl:with-param name="new" select="'%29'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Term" mode="description">
|
|
<xsl:if test="position() = 1">
|
|
<xsl:text>\n\n## Term Definitions\nTerm|Description\n----|----</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>\n</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:variable name="description">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:text>|</xsl:text>
|
|
<xsl:if test="$description!=''">
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string" select="$description"/>
|
|
<xsl:with-param name="old" select="'|'"/>
|
|
<!-- Should actually be '\|' but Swagger tools don't recognize this GFM escape sequence.
|
|
'&#x7c;' works in Swagger Editor but not in Swagger UI -->
|
|
<xsl:with-param name="new" select="'&#x2758;'"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="edmx:Reference" mode="hashvalue">
|
|
<xsl:apply-templates select="@*[local-name()!='Uri']"/>
|
|
<xsl:apply-templates
|
|
select="edmx:IncludeAnnotations[generate-id() = generate-id(key('includeannotations', concat(../@Uri,'|',@TermNamespace))[1])]"
|
|
mode="hash"
|
|
>
|
|
<xsl:with-param name="after"/>
|
|
<xsl:with-param name="key" select="'TermNamespace'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list">
|
|
<xsl:with-param name="after" select="edmx:IncludeAnnotations"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edmx:IncludeAnnotations" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@TermNamespace"/>
|
|
<xsl:text>":[</xsl:text>
|
|
<xsl:for-each select="key('includeannotations', concat(../@Uri,'|',@TermNamespace))">
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:apply-templates select="@*[name()!='TermNamespace']" mode="list"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:for-each>
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edmx:Include" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Namespace"/>
|
|
<xsl:text>":{"uri":"</xsl:text>
|
|
<xsl:call-template name="json-url">
|
|
<xsl:with-param name="url" select="../@Uri"/>
|
|
</xsl:call-template>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
<xsl:if test="@Alias">
|
|
<xsl:text>,"</xsl:text>
|
|
<xsl:value-of select="@Alias"/>
|
|
<xsl:text>":{"aliasFor":"</xsl:text>
|
|
<xsl:value-of select="@Namespace"/>
|
|
<xsl:text>"}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Schema" mode="hashpair">
|
|
<xsl:if test="@Alias">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Alias"/>
|
|
<xsl:text>":{"aliasFor":"</xsl:text>
|
|
<xsl:value-of select="@Namespace"/>
|
|
<xsl:text>"},</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Namespace"/>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list"/>
|
|
<xsl:apply-templates
|
|
select="edm:Annotations[generate-id() = generate-id(key('targets', concat(../@Namespace,'/',@Target))[1])]"
|
|
mode="hash"
|
|
>
|
|
<xsl:with-param name="key" select="'Target'"/>
|
|
<xsl:with-param name="after" select="edm:Annotation"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EnumType" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{"type":"string",</xsl:text>
|
|
<xsl:text>"enum":[</xsl:text>
|
|
<xsl:apply-templates select="edm:Member" mode="enum"/>
|
|
<xsl:text>]</xsl:text>
|
|
<xsl:if test="@IsFlags='true' and $extensions">
|
|
<xsl:text>,"x-isFlags":true</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="x-annotations">
|
|
<xsl:with-param name="annotations" select="edm:Annotation"/>
|
|
<xsl:with-param name="fallback-title" select="@Name"/>
|
|
<xsl:with-param name="members" select="edm:Member/@Value|edm:Member/edm:Annotation"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Member" mode="enum">
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Member/@Value" mode="member">
|
|
<xsl:param name="after"/>
|
|
<xsl:choose>
|
|
<xsl:when test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Name"/>
|
|
<xsl:text>@value":</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Member/edm:Annotation" mode="member">
|
|
<xsl:param name="after"/>
|
|
<xsl:choose>
|
|
<xsl:when test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select=".">
|
|
<xsl:with-param name="target" select="../@Name"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:TypeDefinition" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@UnderlyingType"/>
|
|
<xsl:with-param name="nullableFacet" select="'false'"/>
|
|
</xsl:call-template>
|
|
<xsl:call-template name="x-annotations">
|
|
<xsl:with-param name="annotations" select="edm:Annotation"/>
|
|
<xsl:with-param name="fallback-title" select="@Name"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntityType|edm:ComplexType" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
|
|
<xsl:if test="@BaseType">
|
|
<xsl:if test="$extensions">
|
|
<xsl:text>"x-baseType":"</xsl:text>
|
|
<xsl:call-template name="namespaceQualifiedName">
|
|
<xsl:with-param name="qualifiedName" select="@BaseType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>",</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"allOf":[{</xsl:text>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="@BaseType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>},{</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:text>"type":"object"</xsl:text>
|
|
|
|
<xsl:if test="@Abstract='true' and $extensions">
|
|
<xsl:text>,"x-abstract":true</xsl:text>
|
|
<xsl:if test="local-name()='EntityType' and not(edm:Key)">
|
|
<xsl:text>,"x-keys":[]</xsl:text>
|
|
</xsl:if>
|
|
</xsl:if>
|
|
|
|
<xsl:if test="@HasStream='true' and $extensions">
|
|
<xsl:text>,"x-mediaEntity":true</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@OpenType|edm:Key" mode="list2"/>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="edm:Property|edm:NavigationProperty" mode="hash">
|
|
<xsl:with-param name="name" select="'properties'"/>
|
|
</xsl:apply-templates>
|
|
|
|
<xsl:call-template name="x-annotations">
|
|
<xsl:with-param name="annotations" select="edm:Annotation"/>
|
|
<xsl:with-param name="fallback-title" select="@Name"/>
|
|
</xsl:call-template>
|
|
|
|
<xsl:if test="@BaseType">
|
|
<xsl:text>}]</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Property|edm:NavigationProperty" mode="hashvalue">
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
<xsl:choose>
|
|
<xsl:when test="local-name()='Property'">
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@Unicode" mode="list2"/>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="*[local-name()!='Annotation']" mode="list2"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:if test="$extensions">
|
|
<xsl:text>,"x-relationship":{</xsl:text>
|
|
<xsl:apply-templates
|
|
select="@*[local-name()!='Name' and local-name()!='Type' and local-name()!='Nullable']|node()[local-name()!='ReferentialConstraint' and local-name()!='Annotation']"
|
|
mode="list"/>
|
|
<xsl:apply-templates select="edm:ReferentialConstraint" mode="hash">
|
|
<xsl:with-param name="after"
|
|
select="@*[local-name()!='Name' and local-name()!='Type' and local-name()!='Nullable']|node()[local-name()!='ReferentialConstraint' and local-name()!='Annotation']"/>
|
|
<xsl:with-param name="key" select="'Property'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:call-template name="x-annotations">
|
|
<xsl:with-param name="annotations" select="edm:Annotation"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Term" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
<xsl:apply-templates select="@AppliesTo|@BaseTerm|edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@AppliesTo">
|
|
<!-- TODO: lower-case values? -->
|
|
<xsl:text>"appliesTo":</xsl:text>
|
|
<xsl:variable name="appliesTo" select="normalize-space()"/>
|
|
<xsl:choose>
|
|
<xsl:when test="contains($appliesTo,' ')">
|
|
<xsl:text>["</xsl:text>
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string" select="$appliesTo"/>
|
|
<xsl:with-param name="old" select="' '"/>
|
|
<xsl:with-param name="new" select="'","'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>"]</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@BaseTerm">
|
|
<xsl:text>"baseTerm":"</xsl:text>
|
|
<xsl:call-template name="namespaceQualifiedName">
|
|
<xsl:with-param name="qualifiedName" select="."/>
|
|
</xsl:call-template>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="nullableFacetValue">
|
|
<xsl:param name="type"/>
|
|
<xsl:param name="nullableFacet"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$nullableFacet">
|
|
<xsl:value-of select="$nullableFacet"/>
|
|
</xsl:when>
|
|
<xsl:when test="starts-with($type,'Collection(')">
|
|
<xsl:value-of select="'false'"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="'true'"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="type">
|
|
<xsl:param name="type"/>
|
|
<xsl:param name="nullableFacet"/>
|
|
<xsl:param name="wrap" select="false()"/>
|
|
<xsl:param name="noArray" select="false()"/>
|
|
<xsl:variable name="nullable">
|
|
<xsl:call-template name="nullableFacetValue">
|
|
<xsl:with-param name="type" select="$type"/>
|
|
<xsl:with-param name="nullableFacet" select="$nullableFacet"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="collection" select="starts-with($type,'Collection(')"/>
|
|
<xsl:variable name="singleType">
|
|
<xsl:choose>
|
|
<xsl:when test="$collection">
|
|
<xsl:value-of select="substring-before(substring-after($type,'('),')')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$singleType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="$collection">
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>"title":"Related </xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","type":"object","properties":{"results":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"type":"array","items":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:choose>
|
|
<!--
|
|
<xsl:when test="$singleType='Edm.Stream'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'" />
|
|
<xsl:with-param name="nullable" select="$nullable" />
|
|
<xsl:with-param name="noArray" select="$noArray" />
|
|
</xsl:call-template>
|
|
<xsl:text>,"readOnly":true</xsl:text>
|
|
</xsl:when>
|
|
-->
|
|
<xsl:when test="$singleType='Edm.String'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:apply-templates select="@MaxLength"/>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Binary'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"base64url"</xsl:text>
|
|
<xsl:apply-templates select="@MaxLength">
|
|
<xsl:with-param name="byteLength" select="'yes'"/>
|
|
</xsl:apply-templates>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Boolean'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'boolean'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Decimal'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'number,string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"decimal"</xsl:text>
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@Precision|@Scale[.!=0]" mode="list2"/>
|
|
</xsl:if>
|
|
<xsl:choose>
|
|
<xsl:when test="not(@Scale) or @Scale='0'">
|
|
<xsl:text>,"multipleOf":1</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="@Scale!='variable'">
|
|
<xsl:text>,"multipleOf":1.0e-</xsl:text>
|
|
<xsl:value-of select="@Scale"/>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:if test="@Precision">
|
|
<xsl:variable name="scale">
|
|
<xsl:choose>
|
|
<xsl:when test="not(@Scale)">
|
|
<xsl:value-of select="0"/>
|
|
</xsl:when>
|
|
<xsl:when test="@Scale='variable'">
|
|
<xsl:value-of select="0"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@Scale"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="limit">
|
|
<xsl:call-template name="repeat">
|
|
<xsl:with-param name="string" select="'9'"/>
|
|
<xsl:with-param name="count" select="@Precision - $scale"/>
|
|
</xsl:call-template>
|
|
<xsl:if test="$scale > 0">
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:call-template name="repeat">
|
|
<xsl:with-param name="string" select="'9'"/>
|
|
<xsl:with-param name="count" select="$scale"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:variable>
|
|
<xsl:if test="@Precision < 16">
|
|
<xsl:text>,"minimum":-</xsl:text>
|
|
<xsl:value-of select="$limit"/>
|
|
<xsl:text>,"maximum":</xsl:text>
|
|
<xsl:value-of select="$limit"/>
|
|
</xsl:if>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Byte'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'integer'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"uint8"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.SByte'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'integer'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"int8"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Int16'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'integer'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"int16"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Int32'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'integer'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"int32"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Int64'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'integer,string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"int64"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Date'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"date"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Double'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'number,string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"double"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Single'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'number,string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"float"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Guid'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"uuid"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.DateTimeOffset'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"date-time"</xsl:text>
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@Precision" mode="list2"/>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.TimeOfDay'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"time"</xsl:text>
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@Precision" mode="list2"/>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:when test="$singleType='Edm.Duration'">
|
|
<xsl:call-template name="nullableType">
|
|
<xsl:with-param name="type" select="'string'"/>
|
|
<xsl:with-param name="nullable" select="$nullable"/>
|
|
<xsl:with-param name="noArray" select="$noArray"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"format":"duration"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$qualifier='Edm'">
|
|
<xsl:text>"$ref":"</xsl:text>
|
|
<xsl:value-of select="$odata-schema"/>
|
|
<xsl:text>#/definitions/</xsl:text>
|
|
<xsl:value-of select="$singleType"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:if test="not($nullable='false') and $extensions">
|
|
<xsl:text>,"x-nullable":true</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@SRID" mode="list2"/>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="ref">
|
|
<xsl:with-param name="qualifier" select="$qualifier"/>
|
|
<xsl:with-param name="name">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$singleType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
</xsl:call-template>
|
|
<xsl:if test="not($nullable='false') and $extensions">
|
|
<xsl:text>,"x-nullable":true</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="@MaxLength"/>
|
|
<xsl:if test="$extensions">
|
|
<xsl:apply-templates select="@Precision" mode="list2"/>
|
|
</xsl:if>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select="@DefaultValue">
|
|
<xsl:with-param name="type" select="$singleType"/>
|
|
</xsl:apply-templates>
|
|
<xsl:if test="$collection">
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="ref">
|
|
<xsl:param name="qualifier"/>
|
|
<xsl:param name="name"/>
|
|
<xsl:variable name="internalNamespace" select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
<xsl:variable name="externalNamespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edmx:Include[@Alias=$qualifier]/@Namespace">
|
|
<xsl:value-of select="//edmx:Include[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="//edmx:Include[@Namespace=$qualifier]/@Namespace"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:text>"$ref":"</xsl:text>
|
|
<xsl:call-template name="json-url">
|
|
<xsl:with-param name="url" select="//edmx:Include[@Namespace=$externalNamespace]/../@Uri"/>
|
|
</xsl:call-template>
|
|
<xsl:text>#/definitions/</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$internalNamespace">
|
|
<xsl:value-of select="$internalNamespace"/>
|
|
</xsl:when>
|
|
<xsl:when test="string-length($externalNamespace)>0">
|
|
<xsl:value-of select="$externalNamespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$name"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="schema-ref">
|
|
<xsl:param name="qualifiedName"/>
|
|
<xsl:call-template name="ref">
|
|
<xsl:with-param name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$qualifiedName"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
<xsl:with-param name="name">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$qualifiedName"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="repeat">
|
|
<xsl:param name="string"/>
|
|
<xsl:param name="count"/>
|
|
<xsl:value-of select="$string"/>
|
|
<xsl:if test="$count > 1">
|
|
<xsl:call-template name="repeat">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="count" select="$count - 1"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="nullableType">
|
|
<xsl:param name="type"/>
|
|
<xsl:param name="nullable"/>
|
|
<xsl:param name="noArray"/>
|
|
<xsl:text>"type":</xsl:text>
|
|
<xsl:if test="not($noArray) and (not($nullable='false') or contains($type,','))">
|
|
<xsl:text>[</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$noArray and contains($type,',')">
|
|
<xsl:value-of select="substring-before($type,',')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string" select="$type"/>
|
|
<xsl:with-param name="old" select="','"/>
|
|
<xsl:with-param name="new" select="'","'"/>
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:if test="not($noArray) and not($nullable='false')">
|
|
<xsl:text>,"null"</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="not($noArray) and (not($nullable='false') or contains($type,','))">
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="not($nullable='false') and $extensions">
|
|
<xsl:text>,"x-nullable":true</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@MaxLength">
|
|
<xsl:param name="byteLength"/>
|
|
<xsl:if test=".!='max'">
|
|
<xsl:text>,"maxLength":</xsl:text>
|
|
<xsl:if test="$byteLength and $extensions">
|
|
<xsl:value-of select="4*ceiling(. div 3)"/>
|
|
<xsl:text>,"x-byteLength":</xsl:text>
|
|
</xsl:if>
|
|
<xsl:value-of select="."/>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@Precision">
|
|
<xsl:text>"x-precision":</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@Scale">
|
|
<xsl:text>"x-scale":</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test=".='variable'">
|
|
<xsl:text>"variable"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="."/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@DefaultValue">
|
|
<xsl:param name="type"/>
|
|
<xsl:text>,"default":</xsl:text>
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$type"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="typeName">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$type"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="underlyingType">
|
|
<xsl:choose>
|
|
<xsl:when
|
|
test="//edm:Schema[@Namespace=$qualifier]/edm:TypeDefinition[@Name=$typeName]/@UnderlyingType">
|
|
<xsl:value-of
|
|
select="//edm:Schema[@Namespace=$qualifier]/edm:TypeDefinition[@Name=$typeName]/@UnderlyingType"/>
|
|
</xsl:when>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]/edm:TypeDefinition[@Name=$typeName]/@UnderlyingType">
|
|
<xsl:value-of
|
|
select="//edm:Schema[@Alias=$qualifier]/edm:TypeDefinition[@Name=$typeName]/@UnderlyingType"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="underlyingQualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$underlyingType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when
|
|
test="$underlyingType='Edm.Boolean' or $underlyingType='Edm.Decimal' or $underlyingType='Edm.Double' or $underlyingType='Edm.Single' or $underlyingType='Edm.Byte' or $underlyingType='Edm.SByte' or $underlyingType='Edm.Int16' or $underlyingType='Edm.Int32' or $underlyingType='Edm.Int64'"
|
|
>
|
|
<xsl:value-of select="."/>
|
|
</xsl:when>
|
|
<!-- FAKE: couldn't determine underlying primitive type, so guess from value -->
|
|
<xsl:when test="$underlyingQualifier!='Edm' and (.='true' or .='false' or .='null' or number(.))">
|
|
<xsl:value-of select="."/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="."/>
|
|
</xsl:call-template>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<!-- name : unquoted boolean value -->
|
|
<xsl:template match="@Nullable|@OpenType|@Unicode">
|
|
<xsl:text>"x-</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@ContainsTarget|@IsBound|@IsComposable|@IncludeInServiceDocument">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Key">
|
|
<xsl:text>"x-keys":[</xsl:text>
|
|
<xsl:apply-templates select="edm:PropertyRef" mode="list"/>
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:PropertyRef">
|
|
<xsl:choose>
|
|
<xsl:when test="@Alias">
|
|
<xsl:text>{"</xsl:text>
|
|
<xsl:value-of select="@Alias"/>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"}</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:ReferentialConstraint" mode="item">
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:apply-templates select="@*|node()" mode="list"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Action|edm:Function" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":[</xsl:text>
|
|
<xsl:for-each select="key('methods', concat(../@Namespace,'.',@Name))">
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:text>"parameters":[</xsl:text>
|
|
<xsl:apply-templates select="edm:Parameter" mode="list"/>
|
|
<xsl:text>]</xsl:text>
|
|
<xsl:apply-templates select="edm:ReturnType" mode="list2"/>
|
|
<xsl:apply-templates select="@*[local-name()!='Name']" mode="list2"/>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:for-each>
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Parameter">
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:apply-templates select="@Name"/>
|
|
<xsl:text>,"parameterType":{</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}</xsl:text>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:ReturnType">
|
|
<xsl:text>"returnType":{</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntityContainer">
|
|
<xsl:if test="$extensions">
|
|
<xsl:text>,"x-entityContainer":{</xsl:text>
|
|
<xsl:apply-templates select="@*" mode="list"/>
|
|
<xsl:apply-templates select="edm:EntitySet|edm:Singleton|edm:ActionImport|edm:FunctionImport" mode="hash">
|
|
<xsl:with-param name="name" select="'resources'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet|edm:Singleton" mode="hashvalue">
|
|
<xsl:text>"kind":"</xsl:text>
|
|
<xsl:value-of select="local-name()"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:apply-templates select="@*[local-name()!='Name']" mode="list2"/>
|
|
<xsl:apply-templates select="edm:NavigationPropertyBinding" mode="hash">
|
|
<xsl:with-param name="key" select="'Path'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:NavigationPropertyBinding" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Path"/>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:value-of select="@Target"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:ActionImport|edm:FunctionImport" mode="hashvalue">
|
|
<xsl:text>"kind":"</xsl:text>
|
|
<xsl:value-of select="local-name()"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:apply-templates select="@*[local-name()!='Name']|node()" mode="list2"/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet/@EntityType|edm:Singleton/@Type">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="."/>
|
|
<xsl:with-param name="nullableFacet" select="'false'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:ActionImport/@Action|edm:FunctionImport/@Function">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:call-template name="namespaceQualifiedName">
|
|
<xsl:with-param name="qualifiedName" select="."/>
|
|
</xsl:call-template>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="namespaceQualifiedName">
|
|
<xsl:param name="qualifiedName"/>
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$qualifiedName"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:when test="//edmx:Include[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edmx:Include[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$qualifiedName"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntityContainer" mode="paths">
|
|
<xsl:apply-templates select="edm:EntitySet|edm:Singleton|edm:FunctionImport|edm:ActionImport" mode="list"/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet|edm:Singleton" mode="tags">
|
|
<xsl:if test="position() = 1">
|
|
<xsl:text>,"tags":[</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
|
|
<xsl:variable name="description">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="$description!=''">
|
|
<xsl:text>","description":"</xsl:text>
|
|
<xsl:value-of select="$description"/>
|
|
</xsl:if>
|
|
|
|
<xsl:text>"}</xsl:text>
|
|
<xsl:if test="position() = last()">
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet">
|
|
<xsl:apply-templates select="." mode="entitySet"/>
|
|
<xsl:apply-templates select="." mode="entity"/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet" mode="entitySet">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="@EntityType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="namespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="type">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="@EntityType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="qualifiedType">
|
|
<xsl:value-of select="$namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:variable>
|
|
|
|
<xsl:text>"/</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
|
|
<!-- GET -->
|
|
<xsl:text>"get":{</xsl:text>
|
|
<xsl:text>"summary":"Get entities from </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
|
|
<xsl:variable name="top-supported">
|
|
<xsl:call-template name="capability">
|
|
<xsl:with-param name="term" select="'TopSupported'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="not($top-supported='false')">
|
|
<xsl:text>{"$ref":"#/parameters/top"},</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:variable name="skip-supported">
|
|
<xsl:call-template name="capability">
|
|
<xsl:with-param name="term" select="'SkipSupported'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="not($skip-supported='false')">
|
|
<xsl:text>{"$ref":"#/parameters/skip"},</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:text>{"$ref":"#/parameters/search"},{"$ref":"#/parameters/filter"},{"$ref":"#/parameters/count"}</xsl:text>
|
|
|
|
<xsl:apply-templates select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Property"
|
|
mode="orderby"/>
|
|
<xsl:apply-templates select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Property"
|
|
mode="select"/>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:NavigationProperty"
|
|
mode="expand"/>
|
|
|
|
<xsl:text>],"responses":{"200":{"description":"Retrieved entities","schema":{"type":"object"</xsl:text>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>,"title":"Wrapper","properties":{"d":{"type":"object"</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>,"title":"Collection of </xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:text>,"properties":{</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$odata-version='2.0'">
|
|
<xsl:text>"results"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"value"</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>:{"type":"array","items":{</xsl:text>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}}}</xsl:text>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
|
|
<!-- POST -->
|
|
<xsl:variable name="insertable">
|
|
<xsl:call-template name="capability">
|
|
<xsl:with-param name="term" select="'InsertRestrictions'"/>
|
|
<xsl:with-param name="property" select="'Insertable'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="not($insertable='false')">
|
|
<xsl:text>,"post":{</xsl:text>
|
|
<xsl:text>"summary":"Add new entity to </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[{"name":"</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","in":"body"</xsl:text>
|
|
<xsl:call-template name="entityTypeDescription">
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
<xsl:with-param name="default" select="'New entity'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"schema":{</xsl:text>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}}]</xsl:text>
|
|
<xsl:text>,"responses":{"201":{"description":"Created entity","schema":{</xsl:text>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>"title":"Created </xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","type":"object","properties":{"d":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="capability">
|
|
<xsl:param name="term"/>
|
|
<xsl:param name="property" select="false()"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$property">
|
|
<xsl:value-of
|
|
select="edm:Annotation[@Term=concat($capabilitiesNamespace,'.',$term) or @Term=concat($capabilitiesAlias,'.',$term)]/edm:Record/edm:PropertyValue[@Property=$property]/@Bool|edm:Annotation[@Term=concat($capabilitiesNamespace,'.',$term) or @Term=concat($capabilitiesAlias,'.',$term)]/edm:Record/edm:PropertyValue[@Property=$property]/edm:Bool"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of
|
|
select="edm:Annotation[@Term=concat($capabilitiesNamespace,'.',$term) or @Term=concat($capabilitiesAlias,'.',$term)]/@Bool|edm:Annotation[@Term=concat($capabilitiesNamespace,'.',$term) or @Term=concat($capabilitiesAlias,'.',$term)]/edm:Bool"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Property" mode="orderby">
|
|
<xsl:param name="after" select="'something'"/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:if test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"$orderby","in":"query","description":"Order items by property values</xsl:text>
|
|
<xsl:text>, see [OData Sorting](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374629)"</xsl:text>
|
|
<xsl:text>,"type":"array","uniqueItems":true,"items":{"type":"string"},"enum":[</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text> desc"</xsl:text>
|
|
<xsl:if test="position()=last()">
|
|
<xsl:text>]}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Property" mode="select">
|
|
<xsl:param name="after" select="'something'"/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:if test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"$select","in":"query","description":"Select properties to be returned</xsl:text>
|
|
<xsl:text>, see [OData Select](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374620)"</xsl:text>
|
|
<xsl:text>,"type":"array","uniqueItems":true,"items":{"type":"string"},"enum":[</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:if test="position()=last()">
|
|
<xsl:text>]}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:NavigationProperty" mode="expand">
|
|
<xsl:param name="after" select="'something'"/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:if test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"$expand","in":"query","description":"Expand related entities</xsl:text>
|
|
<xsl:text>, see [OData Expand](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc445374621)"</xsl:text>
|
|
<xsl:text>,"type":"array","uniqueItems":true,"items":{"type":"string"},"enum":["*"</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>,"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:if test="position()=last()">
|
|
<xsl:text>]}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:EntitySet" mode="entity">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="@EntityType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="namespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="type">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="@EntityType"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="qualifiedType">
|
|
<xsl:value-of select="$namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:variable>
|
|
<xsl:variable name="aliasQualifiedType">
|
|
<xsl:value-of select="//edm:Schema[@Namespace=$namespace]/@Alias"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:variable>
|
|
|
|
<xsl:variable name="qualifiedBasetype"
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/@BaseType"/>
|
|
<xsl:variable name="basetypeQualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="$qualifiedBasetype"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="basetypeNamespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$basetypeQualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$basetypeQualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$basetypeQualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="basetype">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$qualifiedBasetype"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
|
|
<!-- entity path template -->
|
|
<xsl:text>,"/</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>(</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef|//edm:Schema[@Namespace=$basetypeNamespace]/edm:EntityType[@Name=$basetype]/edm:Key/edm:PropertyRef"
|
|
mode="path"/>
|
|
<xsl:text>)":{</xsl:text>
|
|
|
|
<!-- GET -->
|
|
<xsl:text>"get":{</xsl:text>
|
|
<xsl:text>"summary":"Get entity from </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text> by key","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef|//edm:Schema[@Namespace=$basetypeNamespace]/edm:EntityType[@Name=$basetype]/edm:Key/edm:PropertyRef"
|
|
mode="parameter"/>
|
|
<xsl:apply-templates select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Property"
|
|
mode="select"/>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:NavigationProperty"
|
|
mode="expand"/>
|
|
<xsl:text>],"responses":{"200":{"description":"Retrieved entity","schema":{</xsl:text>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>"title":"</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","type":"object","properties":{"d":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
|
|
<!-- PATCH -->
|
|
<xsl:variable name="updatable">
|
|
<xsl:call-template name="capability">
|
|
<xsl:with-param name="term" select="'UpdateRestrictions'"/>
|
|
<xsl:with-param name="property" select="'Updatable'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="not($updatable='false')">
|
|
<xsl:text>,"patch":{</xsl:text>
|
|
<xsl:text>"summary":"Update entity in </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef|//edm:Schema[@Namespace=$basetypeNamespace]/edm:EntityType[@Name=$basetype]/edm:Key/edm:PropertyRef"
|
|
mode="parameter"/>
|
|
<xsl:text>,{"name":"</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","in":"body"</xsl:text>
|
|
<xsl:call-template name="entityTypeDescription">
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
<xsl:with-param name="default" select="'New property values'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"schema":{</xsl:text>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>"title":"Modified </xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","type":"object","properties":{"d":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:if test="$odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}}],"responses":{"204":{"description":"Success"},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- DELETE -->
|
|
<xsl:variable name="deletable">
|
|
<xsl:call-template name="capability">
|
|
<xsl:with-param name="term" select="'DeleteRestrictions'"/>
|
|
<xsl:with-param name="property" select="'Deletable'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="not($deletable='false')">
|
|
<xsl:text>,"delete":{</xsl:text>
|
|
<xsl:text>"summary":"Delete entity from </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef|//edm:Schema[@Namespace=$basetypeNamespace]/edm:EntityType[@Name=$basetype]/edm:Key/edm:PropertyRef"
|
|
mode="parameter"/>
|
|
<xsl:text>,{"name":"If-Match","in":"header","description":"ETag","type":"string"}]</xsl:text>
|
|
<xsl:text>,"responses":{"204":{"description":"Success"},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:text>}</xsl:text>
|
|
|
|
<xsl:apply-templates
|
|
select="//edm:Function[@IsBound='true' and (edm:Parameter[1]/@Type=$qualifiedType or edm:Parameter[1]/@Type=$aliasQualifiedType)]"
|
|
mode="bound"
|
|
>
|
|
<xsl:with-param name="entitySet" select="@Name"/>
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates
|
|
select="//edm:Action[@IsBound='true' and (edm:Parameter[1]/@Type=$qualifiedType or edm:Parameter[1]/@Type=$aliasQualifiedType)]"
|
|
mode="bound"
|
|
>
|
|
<xsl:with-param name="entitySet" select="@Name"/>
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Singleton">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="@Type"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="namespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="type">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="@Type"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="qualifiedType">
|
|
<xsl:value-of select="$namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:variable>
|
|
<xsl:variable name="aliasQualifiedType">
|
|
<xsl:value-of select="//edm:Schema[@Namespace=$namespace]/@Alias"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
</xsl:variable>
|
|
|
|
<!-- singleton path template -->
|
|
<xsl:text>"/</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
|
|
<!-- GET -->
|
|
<xsl:text>"get":{</xsl:text>
|
|
<xsl:text>"summary":"Get </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
|
|
<xsl:apply-templates select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Property"
|
|
mode="select"
|
|
>
|
|
<xsl:with-param name="after" select="''"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:NavigationProperty"
|
|
mode="expand"/>
|
|
|
|
<xsl:text>],"responses":{"200":{"description":"Retrieved entity","schema":{</xsl:text>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
|
|
<!-- PATCH -->
|
|
<xsl:text>,"patch":{</xsl:text>
|
|
<xsl:text>"summary":"Update </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>"]</xsl:text>
|
|
<xsl:text>,"parameters":[</xsl:text>
|
|
<xsl:text>{"name":"</xsl:text>
|
|
<xsl:value-of select="$type"/>
|
|
<xsl:text>","in":"body"</xsl:text>
|
|
<xsl:call-template name="entityTypeDescription">
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
<xsl:with-param name="default" select="'New property values'"/>
|
|
</xsl:call-template>
|
|
<xsl:text>,"schema":{</xsl:text>
|
|
<xsl:call-template name="schema-ref">
|
|
<xsl:with-param name="qualifiedName" select="$qualifiedType"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}}],"responses":{"204":{"description":"Success"},</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}</xsl:text>
|
|
|
|
<xsl:text>}</xsl:text>
|
|
|
|
<xsl:apply-templates
|
|
select="//edm:Function[@IsBound='true' and (edm:Parameter[1]/@Type=$qualifiedType or edm:Parameter[1]/@Type=$aliasQualifiedType)]"
|
|
mode="bound"
|
|
>
|
|
<xsl:with-param name="singleton" select="@Name"/>
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:apply-templates>
|
|
<xsl:apply-templates
|
|
select="//edm:Action[@IsBound='true' and (edm:Parameter[1]/@Type=$qualifiedType or edm:Parameter[1]/@Type=$aliasQualifiedType)]"
|
|
mode="bound"
|
|
>
|
|
<xsl:with-param name="singleton" select="@Name"/>
|
|
<xsl:with-param name="namespace" select="$namespace"/>
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="entityTypeDescription">
|
|
<xsl:param name="namespace"/>
|
|
<xsl:param name="type"/>
|
|
<xsl:param name="default"/>
|
|
<xsl:text>,"description":"</xsl:text>
|
|
<xsl:variable name="description">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="$description!=''">
|
|
<xsl:value-of select="$description"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$default"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:PropertyRef" mode="path">
|
|
<xsl:variable name="name" select="@Name"/>
|
|
<xsl:variable name="type" select="../../edm:Property[@Name=$name]/@Type"/>
|
|
<!-- TODO: inheritance - find key definition in base type (recursively) -->
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="last()>1">
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>=</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="pathValuePrefix">
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:call-template>
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>}</xsl:text>
|
|
<xsl:call-template name="pathValueSuffix">
|
|
<xsl:with-param name="type" select="$type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="pathValuePrefix">
|
|
<xsl:param name="type"/>
|
|
<xsl:choose>
|
|
<xsl:when
|
|
test="$type='Edm.Int64' or $type='Edm.Int32' or $type='Edm.Int16' or $type='Edm.SByte' or $type='Edm.Byte' or $type='Edm.Double' or $type='Edm.Single' or $type='Edm.Date' or $type='Edm.DateTimeOffset' or $type='Edm.Guid'"/>
|
|
<!-- TODO: handle other Edm types, enumeration types, and type definitions -->
|
|
<xsl:otherwise>
|
|
<xsl:text>'</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="pathValueSuffix">
|
|
<xsl:param name="type"/>
|
|
<xsl:choose>
|
|
<xsl:when
|
|
test="$type='Edm.Int64' or $type='Edm.Int32' or $type='Edm.Int16' or $type='Edm.SByte' or $type='Edm.Byte' or $type='Edm.Double' or $type='Edm.Single' or $type='Edm.Date' or $type='Edm.DateTimeOffset' or $type='Edm.Guid'"/>
|
|
<!-- TODO: handle other Edm types, enumeration types, and type definitions -->
|
|
<xsl:otherwise>
|
|
<xsl:text>'</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:PropertyRef" mode="parameter">
|
|
<xsl:variable name="name" select="@Name"/>
|
|
<xsl:variable name="type" select="../../edm:Property[@Name=$name]/@Type"/>
|
|
<!-- TODO: inheritance - find key definition in base type (recursively) -->
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","in":"path","required":true,"description":"key: </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","type":</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$type='Edm.Int64'">
|
|
<xsl:text>"integer","format":"int64"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$type='Edm.Int32'">
|
|
<xsl:text>"integer","format":"int32"</xsl:text>
|
|
</xsl:when>
|
|
<!-- TODO: handle other Edm types, enumeration types, and type definitions -->
|
|
<xsl:otherwise>
|
|
<xsl:text>"string"</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:ActionImport">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="@Action"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="namespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="action">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="@Action"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
|
|
<xsl:text>"/</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{"post":{"summary":"</xsl:text>
|
|
<xsl:variable name="summary"
|
|
select="edm:Annotation[@Term=$commonLabel or @Term=$commonLabelAliased]/@String|//edm:Schema/edm:Annotation[@Term=$commonLabel or @Term=$commonLabelAliased]/edm:String"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$summary">
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="$summary"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>Invoke action </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:variable name="action-for" select="edm:Annotation[@Term='SAP.ActionFor']/@String"/>
|
|
<xsl:choose>
|
|
<xsl:when test="@EntitySet">
|
|
<xsl:value-of select="@EntitySet"/>
|
|
</xsl:when>
|
|
<xsl:when test="$action-for">
|
|
<xsl:value-of select="//edm:EntitySet[@EntityType=$action-for]/@Name"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>Service Operations</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>"],"parameters":[</xsl:text>
|
|
<xsl:variable name="parameters"
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:Action[@Name=$action and not(@IsBound='true')]/edm:Parameter"/>
|
|
<xsl:if test="$parameters">
|
|
<xsl:choose>
|
|
<xsl:when test="$odata-version='2.0'">
|
|
<xsl:apply-templates select="$parameters" mode="parameter"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>{"name":"body","in":"body","description":"Action parameters","schema":{"type":"object"</xsl:text>
|
|
<xsl:apply-templates select="$parameters" mode="hash">
|
|
<xsl:with-param name="name" select="'properties'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:if>
|
|
<xsl:text>]</xsl:text>
|
|
|
|
<xsl:call-template name="responses">
|
|
<xsl:with-param name="type"
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:Action[@Name=$action]/edm:ReturnType/@Type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:FunctionImport">
|
|
<xsl:variable name="qualifier">
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="@Function"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="namespace">
|
|
<xsl:choose>
|
|
<xsl:when test="//edm:Schema[@Alias=$qualifier]">
|
|
<xsl:value-of select="//edm:Schema[@Alias=$qualifier]/@Namespace"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="function">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="@Function"/>
|
|
<xsl:with-param name="marker" select="'.'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
|
|
<!-- need to apply templates for all function overloads that match the function name -->
|
|
<xsl:apply-templates select="//edm:Schema[@Namespace=$namespace]/edm:Function[@Name=$function]" mode="import">
|
|
<xsl:with-param name="functionImport" select="@Name"/>
|
|
<xsl:with-param name="entitySet" select="@EntitySet"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Function" mode="import">
|
|
<xsl:param name="functionImport"/>
|
|
<xsl:param name="entitySet"/>
|
|
|
|
<xsl:text>"/</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:if test="$odata-version!='2.0'">
|
|
<xsl:text>(</xsl:text>
|
|
<xsl:apply-templates select="edm:Parameter" mode="path"/>
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>":{"get":{"summary":"</xsl:text>
|
|
<xsl:variable name="summary"
|
|
select="edm:Annotation[@Term=$commonLabel or @Term=$commonLabelAliased]/@String|//edm:Schema/edm:Annotation[@Term=$commonLabel or @Term=$commonLabelAliased]/edm:String"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$summary">
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="$summary"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>Invoke function </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:variable name="action-for" select="edm:Annotation[@Term='SAP.ActionFor']/@String"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$entitySet">
|
|
<xsl:value-of select="$entitySet"/>
|
|
</xsl:when>
|
|
<xsl:when test="$action-for">
|
|
<xsl:value-of select="//edm:EntitySet[@EntityType=$action-for]/@Name"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>Service Operations</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<xsl:text>"],"parameters":[</xsl:text>
|
|
<xsl:apply-templates select="edm:Parameter" mode="parameter"/>
|
|
<xsl:text>]</xsl:text>
|
|
|
|
<xsl:call-template name="responses">
|
|
<xsl:with-param name="type" select="edm:ReturnType/@Type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="responses">
|
|
<xsl:param name="type"/>
|
|
|
|
<xsl:variable name="collection" select="starts-with($type,'Collection(')"/>
|
|
|
|
<xsl:text>,"responses":{</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="not($type)">
|
|
<xsl:text>"204":{"description":"Success"}</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"200":{"description":"Success","schema":{</xsl:text>
|
|
<xsl:if test="$collection or $odata-version='2.0'">
|
|
<xsl:text>"title":"Result","type":"object","properties":{"</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$odata-version='2.0'">
|
|
<xsl:text>d</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>value</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="$type"/>
|
|
<xsl:with-param name="nullableFacet" select="'false'"/>
|
|
</xsl:call-template>
|
|
<xsl:if test="$collection or $odata-version='2.0'">
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>,</xsl:text>
|
|
<xsl:value-of select="$defaultResponse"/>
|
|
<xsl:text>}}}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Action" mode="bound">
|
|
<xsl:param name="entitySet"/>
|
|
<xsl:param name="singleton"/>
|
|
<xsl:param name="namespace"/>
|
|
<xsl:param name="type"/>
|
|
|
|
<xsl:text>,"/</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$entitySet">
|
|
<xsl:value-of select="$entitySet"/>
|
|
<xsl:text>(</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef"
|
|
mode="path"/>
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleton">
|
|
<xsl:value-of select="$singleton"/>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:text>/</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="../@Alias">
|
|
<xsl:value-of select="../@Alias"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>":{"post":{"summary":"Invoke action </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="$entitySet"/>
|
|
<xsl:value-of select="$singleton"/>
|
|
<xsl:text>"],"parameters":[</xsl:text>
|
|
<xsl:if test="$entitySet">
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef"
|
|
mode="parameter"/>
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"body","in":"body","description":"Action parameters","schema":{"type":"object"</xsl:text>
|
|
<xsl:apply-templates select="edm:Parameter[position()>1]" mode="hash">
|
|
<xsl:with-param name="name" select="'properties'"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}}]</xsl:text>
|
|
|
|
<xsl:call-template name="responses">
|
|
<xsl:with-param name="type" select="edm:ReturnType/@Type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Function" mode="bound">
|
|
<xsl:param name="entitySet"/>
|
|
<xsl:param name="singleton"/>
|
|
<xsl:param name="namespace"/>
|
|
<xsl:param name="type"/>
|
|
<xsl:variable name="singleReturnType">
|
|
<xsl:choose>
|
|
<xsl:when test="starts-with(edm:ReturnType/@Type,'Collection(')">
|
|
<xsl:value-of select="substring-before(substring-after(edm:ReturnType/@Type,'('),')')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="edm:ReturnType/@Type"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<xsl:text>,"/</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$entitySet">
|
|
<xsl:value-of select="$entitySet"/>
|
|
<xsl:text>(</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef"
|
|
mode="path"/>
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$singleton">
|
|
<xsl:value-of select="$singleton"/>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:text>/</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="../@Alias">
|
|
<xsl:value-of select="../@Alias"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="../@Namespace"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>(</xsl:text>
|
|
<xsl:apply-templates select="edm:Parameter[position()>1]" mode="path"/>
|
|
<xsl:text>)":{"get":{"summary":"Invoke function </xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","tags":["</xsl:text>
|
|
<xsl:value-of select="$entitySet"/>
|
|
<xsl:value-of select="$singleton"/>
|
|
<xsl:text>"],"parameters":[</xsl:text>
|
|
<xsl:apply-templates
|
|
select="//edm:Schema[@Namespace=$namespace and $entitySet]/edm:EntityType[@Name=$type]/edm:Key/edm:PropertyRef|edm:Parameter[position()>1]"
|
|
mode="parameter"/>
|
|
<xsl:text>]</xsl:text>
|
|
|
|
<xsl:call-template name="responses">
|
|
<xsl:with-param name="type" select="edm:ReturnType/@Type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Action/edm:Parameter" mode="hashvalue">
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Action/edm:Parameter|edm:Function/edm:Parameter" mode="parameter">
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>{"name":"</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$odata-version='2.0'">
|
|
<xsl:text>","in":"query"</xsl:text>
|
|
<xsl:if test="@Nullable='false'">
|
|
<xsl:text>,"required":true</xsl:text>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>","in":"path"</xsl:text>
|
|
<xsl:text>,"required":true</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>,</xsl:text>
|
|
<xsl:call-template name="type">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
<xsl:with-param name="nullableFacet" select="@Nullable"/>
|
|
<xsl:with-param name="noArray" select="true()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Parameter/@MaxLength">
|
|
<xsl:if test=".!='max'">
|
|
<xsl:text>,"maxLength":</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Function/edm:Parameter" mode="path">
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>=</xsl:text>
|
|
<xsl:call-template name="pathValueSuffix">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
</xsl:call-template>
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>}</xsl:text>
|
|
<xsl:call-template name="pathValueSuffix">
|
|
<xsl:with-param name="type" select="@Type"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Annotations" mode="hashpair">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Target"/>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:for-each select="key('targets', concat(../@Namespace,'/',@Target))">
|
|
<xsl:if test="position()>1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="*" mode="list">
|
|
<xsl:with-param name="qualifier" select="@Qualifier"/>
|
|
</xsl:apply-templates>
|
|
</xsl:for-each>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="x-annotations">
|
|
<xsl:param name="annotations"/>
|
|
<xsl:param name="members" select="null"/>
|
|
<xsl:param name="fallback-title" select="null"/>
|
|
|
|
<xsl:variable name="title">
|
|
<xsl:call-template name="Common.Label">
|
|
<xsl:with-param name="node" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="$title!=''">
|
|
<xsl:text>,"title":"</xsl:text>
|
|
<xsl:value-of select="$title"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$fallback-title">
|
|
<xsl:text>,"title":"</xsl:text>
|
|
<xsl:value-of select="$fallback-title"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
|
|
<xsl:variable name="description">
|
|
<xsl:call-template name="Core.Description">
|
|
<xsl:with-param name="node" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:if test="$description!=''">
|
|
<xsl:text>,"description":"</xsl:text>
|
|
<xsl:value-of select="$description"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:variable name="remaining"
|
|
select="$annotations[not((@Term=$coreDescription or @Term=$coreDescriptionAliased or @Term=$commonLabel or @Term=$commonLabelAliased) and not(@Qualifier) and (@String or edm:String))]"/>
|
|
<xsl:if test="($remaining or $members) and $extensions">
|
|
<xsl:text>,"x-annotations":{</xsl:text>
|
|
<xsl:apply-templates select="$remaining" mode="list"/>
|
|
<xsl:if test="$members">
|
|
<xsl:apply-templates select="$members" mode="member">
|
|
<xsl:with-param name="after" select="$remaining"/>
|
|
</xsl:apply-templates>
|
|
</xsl:if>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Annotation">
|
|
<xsl:param name="target"/>
|
|
<xsl:param name="qualifier"/>
|
|
<xsl:variable name="name">
|
|
<xsl:value-of select="$target"/>
|
|
<xsl:text>@</xsl:text>
|
|
<xsl:value-of select="@Term"/>
|
|
<xsl:if test="@Qualifier or $qualifier">
|
|
<xsl:text>#</xsl:text>
|
|
<xsl:value-of select="@Qualifier"/>
|
|
<xsl:value-of select="$qualifier"/>
|
|
</xsl:if>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<!-- TODO: remove choice, just do xsl:otherwise; remove "normalize" parameter from @String|edm:String template -->
|
|
<xsl:when
|
|
test="(substring($name,2)=$coreDescription or substring($name,2)=$coreDescriptionAliased) and (@String or edm:String)">
|
|
<xsl:text>"description":</xsl:text>
|
|
<xsl:apply-templates select="@String|edm:String">
|
|
<xsl:with-param name="normalize" select="true()"/>
|
|
</xsl:apply-templates>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="$name"/>
|
|
<xsl:text>":</xsl:text>
|
|
<xsl:apply-templates
|
|
select="@*[local-name()!='Term' and local-name()!='Qualifier']|*[local-name()!='Annotation']"
|
|
mode="list"
|
|
>
|
|
<xsl:with-param name="target" select="$name"/>
|
|
</xsl:apply-templates>
|
|
<xsl:if test="count(@*[local-name()!='Term' and local-name()!='Qualifier']|*[local-name()!='Annotation'])=0">
|
|
<!-- tagging term -->
|
|
<!-- TODO: try to get default value from term definition, use true if not possible -->
|
|
<xsl:text>true</xsl:text>
|
|
</xsl:if>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2">
|
|
<xsl:with-param name="target" select="$name"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<!-- name : unquoted direct value or annotated quoted special value -->
|
|
<xsl:template match="@Float|edm:Float">
|
|
<xsl:choose>
|
|
<xsl:when test=".='INF' or .='-INF' or .='NaN'">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="."/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<!-- unquoted direct value -->
|
|
<xsl:template match="@Bool|edm:Bool|@Decimal|edm:Decimal|@Int|edm:Int">
|
|
<xsl:value-of select="."/>
|
|
</xsl:template>
|
|
|
|
<!-- direct quoted value -->
|
|
<xsl:template
|
|
match="@Binary|edm:Binary|@Date|edm:Date|@DateTimeOffset|edm:DateTimeOffset|@Duration|edm:Duration|@Guid|edm:Guid|@TimeOfDay|edm:TimeOfDay"
|
|
>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="@EnumMember|edm:EnumMember">
|
|
<xsl:variable name="type" select="substring-before(.,'/')"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string">
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string" select="."/>
|
|
<xsl:with-param name="old" select="concat($type,'/')"/>
|
|
<xsl:with-param name="new" select="''"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
<xsl:with-param name="old" select="' '"/>
|
|
<xsl:with-param name="new" select="','"/>
|
|
</xsl:call-template>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- name : object with escaped string value -->
|
|
<xsl:template
|
|
match="@AnnotationPath|edm:AnnotationPath|@NavigationPropertyPath|edm:NavigationPropertyPath|@Path|edm:Path|@PropertyPath|edm:PropertyPath|@UrlRef"
|
|
>
|
|
<xsl:text>{"@</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="normalize-space(.)"/>
|
|
</xsl:call-template>
|
|
<xsl:text>"}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- escaped string value -->
|
|
<xsl:template match="@String|edm:String">
|
|
<xsl:param name="normalize" select="false()"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$normalize">
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="normalize-space(.)"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="escape">
|
|
<xsl:param name="string"/>
|
|
<xsl:choose>
|
|
<xsl:when test="contains($string,'"')">
|
|
<xsl:call-template name="replace">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="old" select="'"'"/>
|
|
<xsl:with-param name="new" select="'\"'"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:when test="contains($string,'\')">
|
|
<xsl:call-template name="replace">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="old" select="'\'"/>
|
|
<xsl:with-param name="new" select="'\\'"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:when test="contains($string,'
')">
|
|
<xsl:call-template name="replace">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="old" select="'
'"/>
|
|
<xsl:with-param name="new" select="'\n'"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:when test="contains($string,'
')">
|
|
<xsl:call-template name="replace">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="old" select="'
'"/>
|
|
<xsl:with-param name="new" select="'\r'"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:when test="contains($string,'	')">
|
|
<xsl:call-template name="replace">
|
|
<xsl:with-param name="string" select="$string"/>
|
|
<xsl:with-param name="old" select="'	'"/>
|
|
<xsl:with-param name="new" select="'\t'"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$string"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="replace">
|
|
<xsl:param name="string"/>
|
|
<xsl:param name="old"/>
|
|
<xsl:param name="new"/>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="substring-before($string,$old)"/>
|
|
</xsl:call-template>
|
|
<xsl:value-of select="$new"/>
|
|
<xsl:call-template name="escape">
|
|
<xsl:with-param name="string" select="substring-after($string,$old)"/>
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Record">
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:if test="@Type">
|
|
<xsl:text>"@type":"#</xsl:text>
|
|
<xsl:value-of select="@Type"/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="*" mode="list">
|
|
<xsl:with-param name="after" select="@Type"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:PropertyValue">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@Property"/>
|
|
<xsl:text>":</xsl:text>
|
|
<xsl:apply-templates select="@*[local-name()!='Property']|node()[local-name()!='Annotation']"/>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2">
|
|
<xsl:with-param name="target" select="@Property"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Collection">
|
|
<xsl:text>[</xsl:text>
|
|
<xsl:apply-templates select="node()" mode="list"/>
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:If|edm:Eq|edm:Ne|edm:Ge|edm:Gt|edm:Le|edm:Lt|edm:And|edm:Or">
|
|
<xsl:text>{"@</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":[</xsl:text>
|
|
<xsl:apply-templates select="*[local-name()!='Annotation']" mode="list"/>
|
|
<xsl:text>]</xsl:text>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Apply">
|
|
<xsl:text>{"@apply":"</xsl:text>
|
|
<xsl:value-of select="@Function"/>
|
|
<xsl:text>","parameterValues":[</xsl:text>
|
|
<xsl:apply-templates select="*[local-name()!='Annotation']" mode="list"/>
|
|
<xsl:text>]</xsl:text>
|
|
<xsl:apply-templates select="edm:Annotation" mode="list2"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Cast|edm:IsOf">
|
|
<xsl:text>{"@</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:value-of select="@Type"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:apply-templates select="@MaxLength"/>
|
|
<xsl:apply-templates select="@*[local-name()!='Type' and local-name()!='MaxLength']" mode="list2"/>
|
|
<xsl:text>,"value":</xsl:text>
|
|
<xsl:apply-templates select="node()"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:LabeledElement">
|
|
<xsl:text>{"@labeledElement":"</xsl:text>
|
|
<xsl:value-of select="ancestor::edm:Schema/@Namespace"/>
|
|
<xsl:text>.</xsl:text>
|
|
<xsl:value-of select="@Name"/>
|
|
<xsl:text>","value":</xsl:text>
|
|
<xsl:apply-templates select="@*[local-name()!='Name']|node()"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:LabeledElementReference">
|
|
<xsl:text>{"@labeledElementReference":"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Null">
|
|
<xsl:choose>
|
|
<xsl:when test="@*|node()">
|
|
<xsl:text>{"@null":{</xsl:text>
|
|
<xsl:apply-templates select="@*|node()" mode="list"/>
|
|
<xsl:text>}}</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>null</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="edm:Not|edm:UrlRef">
|
|
<xsl:text>{"@</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":</xsl:text>
|
|
<xsl:apply-templates select="@*|node()"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- name : object -->
|
|
<xsl:template match="@*|*" mode="object">
|
|
<xsl:param name="name"/>
|
|
<xsl:param name="after" select="'something'"/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:if test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="$name"/>
|
|
<xsl:text>":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="."/>
|
|
<xsl:if test="position()!=last()">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position()=last()">
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<!-- object within array -->
|
|
<xsl:template match="*" mode="item">
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:apply-templates select="@*|node()" mode="list"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- pluralize(name) : hash -->
|
|
<xsl:template match="*" mode="hash">
|
|
<xsl:param name="name"/>
|
|
<xsl:param name="key" select="'Name'"/>
|
|
<xsl:param name="after" select="'something'"/>
|
|
<xsl:param name="constantProperties"/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:if test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:choose>
|
|
<xsl:when test="$name">
|
|
<xsl:value-of select="$name"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="pluralize">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:text>":{</xsl:text>
|
|
</xsl:if>
|
|
<xsl:apply-templates select="." mode="hashpair">
|
|
<xsl:with-param name="name" select="$name"/>
|
|
<xsl:with-param name="key" select="$key"/>
|
|
</xsl:apply-templates>
|
|
<xsl:if test="position()!=last()">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
<xsl:if test="position()=last()">
|
|
<xsl:value-of select="$constantProperties"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="*" mode="hashpair">
|
|
<xsl:param name="name"/>
|
|
<xsl:param name="key" select="'Name'"/>
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select="@*[local-name()=$key]"/>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:apply-templates select="." mode="hashvalue">
|
|
<xsl:with-param name="name" select="$name"/>
|
|
<xsl:with-param name="key" select="$key"/>
|
|
</xsl:apply-templates>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="*" mode="hashvalue">
|
|
<xsl:param name="key" select="'Name'"/>
|
|
<xsl:apply-templates select="@*[local-name()!=$key]|node()" mode="list"/>
|
|
</xsl:template>
|
|
|
|
<!-- comma-separated list -->
|
|
<xsl:template match="@*|*" mode="list">
|
|
<xsl:param name="target"/>
|
|
<xsl:param name="qualifier"/>
|
|
<xsl:param name="after"/>
|
|
<xsl:choose>
|
|
<xsl:when test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$after">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select=".">
|
|
<xsl:with-param name="target" select="$target"/>
|
|
<xsl:with-param name="qualifier" select="$qualifier"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<!-- continuation of comma-separated list -->
|
|
<xsl:template match="@*|*" mode="list2">
|
|
<xsl:param name="target"/>
|
|
<xsl:param name="qualifier"/>
|
|
<xsl:text>,</xsl:text>
|
|
<xsl:apply-templates select=".">
|
|
<xsl:with-param name="target" select="$target"/>
|
|
<xsl:with-param name="qualifier" select="$qualifier"/>
|
|
</xsl:apply-templates>
|
|
</xsl:template>
|
|
|
|
<!-- name : quoted value -->
|
|
<xsl:template match="@*">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- name : object -->
|
|
<xsl:template match="*">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:call-template name="lowerCamelCase">
|
|
<xsl:with-param name="name" select="local-name()"/>
|
|
</xsl:call-template>
|
|
<xsl:text>":{</xsl:text>
|
|
<xsl:apply-templates select="@*|node()" mode="list"/>
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- leftover text -->
|
|
<xsl:template match="text()">
|
|
<xsl:text>"TODO:text()":"</xsl:text>
|
|
<xsl:value-of select="."/>
|
|
<xsl:text>"</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- helper functions -->
|
|
<xsl:template name="pluralize">
|
|
<xsl:param name="name"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$name='Annotations'">
|
|
<xsl:text>annotations</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$name='IncludeAnnotations'">
|
|
<xsl:text>includeAnnotations</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$name='NavigationProperty'">
|
|
<xsl:text>navigationProperties</xsl:text>
|
|
</xsl:when>
|
|
<xsl:when test="$name='Property'">
|
|
<xsl:text>properties</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of
|
|
select="translate(substring($name,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
|
|
<xsl:value-of select="substring($name,2)"/>
|
|
<xsl:text>s</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="lowerCamelCase">
|
|
<xsl:param name="name"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$name='SRID'">
|
|
<xsl:text>x-srid</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of
|
|
select="translate(substring($name,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
|
|
<xsl:value-of select="substring($name,2)"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="substring-before-last">
|
|
<xsl:param name="input"/>
|
|
<xsl:param name="marker"/>
|
|
<xsl:if test="contains($input,$marker)">
|
|
<xsl:value-of select="substring-before($input,$marker)"/>
|
|
<xsl:if test="contains(substring-after($input,$marker),$marker)">
|
|
<xsl:value-of select="$marker"/>
|
|
<xsl:call-template name="substring-before-last">
|
|
<xsl:with-param name="input" select="substring-after($input,$marker)"/>
|
|
<xsl:with-param name="marker" select="$marker"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="substring-after-last">
|
|
<xsl:param name="input"/>
|
|
<xsl:param name="marker"/>
|
|
<xsl:choose>
|
|
<xsl:when test="contains($input,$marker)">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="substring-after($input,$marker)"/>
|
|
<xsl:with-param name="marker" select="$marker"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$input"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="replace-all">
|
|
<xsl:param name="string"/>
|
|
<xsl:param name="old"/>
|
|
<xsl:param name="new"/>
|
|
<xsl:choose>
|
|
<xsl:when test="contains($string,$old)">
|
|
<xsl:value-of select="substring-before($string,$old)"/>
|
|
<xsl:value-of select="$new"/>
|
|
<xsl:call-template name="replace-all">
|
|
<xsl:with-param name="string" select="substring-after($string,$old)"/>
|
|
<xsl:with-param name="old" select="$old"/>
|
|
<xsl:with-param name="new" select="$new"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$string"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="json-url">
|
|
<xsl:param name="url"/>
|
|
<xsl:variable name="jsonUrl">
|
|
<xsl:choose>
|
|
<xsl:when test="substring($url,string-length($url)-3) = '.xml'">
|
|
<xsl:choose>
|
|
<xsl:when test="substring($url,1,33) = 'http://docs.oasis-open.org/odata/'">
|
|
<xsl:value-of select="$vocabulary-home"/>
|
|
<xsl:text>/</xsl:text>
|
|
<xsl:variable name="filename">
|
|
<xsl:call-template name="substring-after-last">
|
|
<xsl:with-param name="input" select="$url"/>
|
|
<xsl:with-param name="marker" select="'/'"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:value-of select="substring($filename,1,string-length($filename)-4)"/>
|
|
<!-- TODO: no .openapi in final destination -->
|
|
<xsl:value-of select="'.openapi.json'"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="substring($url,1,string-length($url)-4)"/>
|
|
<xsl:value-of select="'.openapi.json'"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:when>
|
|
<xsl:when test="string-length($url) = 0">
|
|
<xsl:value-of select="$url"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$url"/>
|
|
<xsl:value-of select="$openapi-formatoption"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:choose>
|
|
<xsl:when test="substring($jsonUrl,1,1) = '/'">
|
|
<xsl:value-of select="$scheme"/>
|
|
<xsl:text>://</xsl:text>
|
|
<xsl:value-of select="$host"/>
|
|
<xsl:value-of select="$jsonUrl"/>
|
|
</xsl:when>
|
|
<xsl:when test="substring($jsonUrl,1,3) = '../'">
|
|
<xsl:value-of select="$scheme"/>
|
|
<xsl:text>://</xsl:text>
|
|
<xsl:value-of select="$host"/>
|
|
<xsl:value-of select="$basePath"/>
|
|
<xsl:text>/</xsl:text>
|
|
<xsl:value-of select="$jsonUrl"/>
|
|
</xsl:when>
|
|
<!-- TODO: more rules for recognizing relative URLs and doing the needful -->
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$jsonUrl"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
</xsl:stylesheet> |