| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| wadl.xsl (07-Sep-2012) |
| |
| Transforms Web Application Description Language (WADL) XML documents into HTML. |
| |
| Mark Sawers <mark.sawers@ipc.com> |
| |
| See example_wadl.xml at http://github.com/ipcsystems/wadl-stylesheet to explore this stylesheet's capabilities |
| and the README.txt for other usage information. |
| Note that the contents of a doc element is rendered as a: |
| * hyperlink if the title attribute contains is equal to 'Example' |
| * mono-spaced font ('pre' tag) if content contains the text 'Example' |
| |
| Limitations: |
| * Ignores globally defined methods, referred to from a resource using a method reference element. |
| Methods must be embedded in a resource element. |
| * Ditto for globally defined representations. Representations must be embedded within request |
| and response elements. |
| * Ignores type and queryType attributes of resource element. |
| * Ignores resource_type element. |
| * Ignores profile attribute of representation element. |
| * Ignores path attribute and child link elements of param element. |
| |
| Copyright (c) 2012 IPC Systems, Inc. |
| |
| Parts of this work are adapted from Mark Notingham's wadl_documentation.xsl, at |
| https://github.com/mnot/wadl_stylesheets. |
| |
| This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 License. |
| To view a copy of this license, visit |
| http://creativecommons.org/licenses/by-sa/3.0/ |
| or send a letter to |
| Creative Commons |
| 543 Howard Street, 5th Floor |
| San Francisco, California, 94105, USA |
| --> |
| <xsl:stylesheet |
| xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" |
| xmlns:wadl="http://wadl.dev.java.net/2009/02" |
| xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| xmlns:html="http://www.w3.org/1999/xhtml" |
| xmlns="http://www.w3.org/1999/xhtml" |
| > |
| |
| <!-- Global variables --> |
| <xsl:variable name="g_resourcesBase" select="wadl:application/wadl:resources/@base"/> |
| |
| <!-- Template for top-level doc element --> |
| <xsl:template match="wadl:application"> |
| <html> |
| <head> |
| <meta charset="UTF-8" /> |
| <xsl:call-template name="getStyle"/> |
| <title><xsl:call-template name="getTitle"/></title> |
| </head> |
| <body> |
| <h1><xsl:call-template name="getTitle"/></h1> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="$g_resourcesBase"/> |
| </xsl:call-template> |
| |
| <!-- Summary --> |
| <h2>Summary</h2> |
| <table> |
| <tr> |
| <th>Resource</th> |
| <th>Method</th> |
| <th>Description</th> |
| </tr> |
| <xsl:for-each select="wadl:resources/wadl:resource"> |
| <xsl:call-template name="processResourceSummary"> |
| <xsl:with-param name="resourceBase" select="$g_resourcesBase"/> |
| <xsl:with-param name="resourcePath" select="@path"/> |
| <xsl:with-param name="lastResource" select="position() = last()"/> |
| </xsl:call-template> |
| </xsl:for-each> |
| </table> |
| <p></p> |
| |
| <!-- Grammars --> |
| <xsl:if test="wadl:grammars/wadl:include"> |
| <h2>Grammars</h2> |
| <p> |
| <xsl:for-each select="wadl:grammars/wadl:include"> |
| <xsl:variable name="href" select="@href"/> |
| <a href="{$href}"><xsl:value-of select="$href"/></a> |
| <xsl:if test="position() != last()"><br/></xsl:if> <!-- Add a spacer --> |
| </xsl:for-each> |
| </p> |
| </xsl:if> |
| |
| <!-- Detail --> |
| <h2>Resources</h2> |
| <xsl:for-each select="wadl:resources"> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="$g_resourcesBase"/> |
| </xsl:call-template> |
| <br/> |
| </xsl:for-each> |
| |
| <xsl:for-each select="wadl:resources/wadl:resource"> |
| <xsl:call-template name="processResourceDetail"> |
| <xsl:with-param name="resourceBase" select="$g_resourcesBase"/> |
| <xsl:with-param name="resourcePath" select="@path"/> |
| </xsl:call-template> |
| </xsl:for-each> |
| |
| </body> |
| </html> |
| </xsl:template> |
| |
| <!-- Supporting templates (functions) --> |
| |
| <xsl:template name="processResourceSummary"> |
| <xsl:param name="resourceBase"/> |
| <xsl:param name="resourcePath"/> |
| <xsl:param name="lastResource"/> |
| |
| <xsl:if test="wadl:method"> |
| <tr> |
| <!-- Resource --> |
| <td class="summary"> |
| <xsl:variable name="id"><xsl:call-template name="getId"/></xsl:variable> |
| <a href="#{$id}"> |
| <xsl:call-template name="getFullResourcePath"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| <xsl:with-param name="path" select="$resourcePath"/> |
| </xsl:call-template> |
| </a> |
| </td> |
| <!-- Method --> |
| <td class="summary"> |
| <xsl:for-each select="wadl:method"> |
| <xsl:variable name="name" select="@name"/> |
| <xsl:variable name="id2"><xsl:call-template name="getId"/></xsl:variable> |
| <a href="#{$id2}"><xsl:value-of select="$name"/></a> |
| <xsl:for-each select="wadl:doc"><br/></xsl:for-each> |
| <xsl:if test="position() != last()"><br/></xsl:if> <!-- Add a spacer --> |
| </xsl:for-each> |
| <br/> |
| </td> |
| <!-- Description --> |
| <td class="summary"> |
| <xsl:for-each select="wadl:method"> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| </xsl:call-template> |
| <br/> |
| <xsl:if test="position() != last()"><br/></xsl:if> <!-- Add a spacer --> |
| </xsl:for-each> |
| </td> |
| </tr> |
| <!-- Add separator if not the last resource --> |
| <xsl:if test="wadl:method and not($lastResource)"> |
| <tr><td class="summarySeparator"></td><td class="summarySeparator"/><td class="summarySeparator"/></tr> |
| </xsl:if> |
| </xsl:if> <!-- wadl:method --> |
| |
| <!-- Call recursively for child resources --> |
| <xsl:for-each select="wadl:resource"> |
| <xsl:variable name="base"> |
| <xsl:call-template name="getFullResourcePath"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| <xsl:with-param name="path" select="$resourcePath"/> |
| </xsl:call-template> |
| </xsl:variable> |
| <xsl:call-template name="processResourceSummary"> |
| <xsl:with-param name="resourceBase" select="$base"/> |
| <xsl:with-param name="resourcePath" select="@path"/> |
| <xsl:with-param name="lastResource" select="$lastResource and position() = last()"/> |
| </xsl:call-template> |
| </xsl:for-each> |
| |
| </xsl:template> |
| |
| <xsl:template name="processResourceDetail"> |
| <xsl:param name="resourceBase"/> |
| <xsl:param name="resourcePath"/> |
| |
| <xsl:if test="wadl:method"> |
| <h3> |
| <xsl:variable name="id"><xsl:call-template name="getId"/></xsl:variable> |
| <a name="{$id}"> |
| <xsl:call-template name="getFullResourcePath"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| <xsl:with-param name="path" select="$resourcePath"/> |
| </xsl:call-template> |
| </a> |
| </h3> |
| <p> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| </xsl:call-template> |
| </p> |
| |
| <h5>Methods</h5> |
| |
| <div class="methods"> |
| <xsl:for-each select="wadl:method"> |
| <div class="method"> |
| <table class="methodNameTable"> |
| <tr> |
| <td class="methodNameTd" style="font-weight: bold"> |
| <xsl:variable name="name" select="@name"/> |
| <xsl:variable name="id2"><xsl:call-template name="getId"/></xsl:variable> |
| <a name="{$id2}"><xsl:value-of select="$name"/></a> |
| </td> |
| <td class="methodNameTd" style="text-align: right"> |
| <xsl:if test="@id"> |
| <xsl:value-of select="@id"/>() |
| </xsl:if> |
| </td> |
| </tr> |
| </table> |
| <p> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| </xsl:call-template> |
| </p> |
| |
| <!-- Request --> |
| <h6>request</h6> |
| <div style="margin-left: 2em"> <!-- left indent --> |
| <xsl:choose> |
| <xsl:when test="wadl:request"> |
| <xsl:for-each select="wadl:request"> |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'template'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'matrix'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'header'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'query'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getRepresentations"/> |
| </xsl:for-each> <!-- wadl:request --> |
| </xsl:when> |
| |
| <xsl:when test="not(wadl:request) and (ancestor::wadl:*/wadl:param)"> |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'template'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'matrix'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'header'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getParamBlock"> |
| <xsl:with-param name="style" select="'query'"/> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getRepresentations"/> |
| </xsl:when> |
| |
| <xsl:otherwise> |
| unspecified |
| </xsl:otherwise> |
| </xsl:choose> |
| </div> <!-- left indent for request --> |
| |
| <!-- Response --> |
| <h6>responses</h6> |
| <div style="margin-left: 2em"> <!-- left indent --> |
| <xsl:choose> |
| <xsl:when test="wadl:response"> |
| <xsl:for-each select="wadl:response"> |
| <div class="h8">status: </div> |
| <xsl:choose> |
| <xsl:when test="@status"> |
| <xsl:value-of select="@status"/> |
| </xsl:when> |
| <xsl:otherwise> |
| 200 - OK |
| </xsl:otherwise> |
| </xsl:choose> |
| <xsl:for-each select="wadl:doc"> |
| <xsl:if test="@title"> |
| - <xsl:value-of select="@title"/> |
| </xsl:if> |
| <xsl:if test="text()"> |
| - <xsl:value-of select="text()"/> |
| </xsl:if> |
| </xsl:for-each> |
| |
| <!-- Get response headers/representations --> |
| <xsl:if test="wadl:param or wadl:representation"> |
| <div style="margin-left: 2em"> <!-- left indent --> |
| <xsl:if test="wadl:param"> |
| <div class="h7">headers</div> |
| <table> |
| <xsl:for-each select="wadl:param[@style='header']"> |
| <xsl:call-template name="getParams"/> |
| </xsl:for-each> |
| </table> |
| </xsl:if> |
| |
| <xsl:call-template name="getRepresentations"/> |
| </div> <!-- left indent for response headers/representations --> |
| </xsl:if> |
| </xsl:for-each> <!-- wadl:response --> |
| </xsl:when> |
| <xsl:otherwise> |
| unspecified |
| </xsl:otherwise> |
| </xsl:choose> |
| </div> <!-- left indent for responses --> |
| |
| </div> <!-- class=method --> |
| </xsl:for-each> <!-- wadl:method --> |
| </div> <!-- class=methods --> |
| |
| </xsl:if> <!-- wadl:method --> |
| |
| <!-- Call recursively for child resources --> |
| <xsl:for-each select="wadl:resource"> |
| <xsl:variable name="base"> |
| <xsl:call-template name="getFullResourcePath"> |
| <xsl:with-param name="base" select="$resourceBase"/> |
| <xsl:with-param name="path" select="$resourcePath"/> |
| </xsl:call-template> |
| </xsl:variable> |
| <xsl:call-template name="processResourceDetail"> |
| <xsl:with-param name="resourceBase" select="$base"/> |
| <xsl:with-param name="resourcePath" select="@path"/> |
| </xsl:call-template> |
| </xsl:for-each> <!-- wadl:resource --> |
| </xsl:template> |
| |
| <xsl:template name="getFullResourcePath"> |
| <xsl:param name="base"/> |
| <xsl:param name="path"/> |
| <xsl:choose> |
| <xsl:when test="substring($base, string-length($base)) = '/'"> |
| <xsl:value-of select="$base"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="concat($base, '/')"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| <xsl:choose> |
| <xsl:when test="starts-with($path, '/')"> |
| <xsl:value-of select="substring($path, 2)"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$path"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:template> |
| |
| <xsl:template name="getDoc"> |
| <xsl:param name="base"/> |
| <xsl:for-each select="wadl:doc"> |
| <xsl:if test="position() > 1"><br/></xsl:if> |
| <xsl:if test="@title and local-name(..) != 'application'"> |
| <xsl:value-of select="@title"/>: |
| </xsl:if> |
| <xsl:variable name="content" select="."/> |
| <xsl:choose> |
| <xsl:when test="@title = 'Example'"> |
| <xsl:variable name="url"> |
| <xsl:choose> |
| <xsl:when test="string-length($base) > 0"> |
| <xsl:call-template name="getFullResourcePath"> |
| <xsl:with-param name="base" select="$base"/> |
| <xsl:with-param name="path" select="text()"/> |
| </xsl:call-template> |
| </xsl:when> |
| <xsl:otherwise><xsl:value-of select="text()"/></xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| <a href="{$url}"><xsl:value-of select="$url"/></a> |
| </xsl:when> |
| <xsl:when test="contains($content, 'Example')"> |
| <div style="white-space:pre-wrap"><pre><xsl:value-of select="."/></pre></div> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$content" disable-output-escaping="yes"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:for-each> |
| </xsl:template> |
| |
| <xsl:template name="getId"> |
| <xsl:choose> |
| <xsl:when test="@id"><xsl:value-of select="@id"/></xsl:when> |
| <xsl:otherwise><xsl:value-of select="generate-id()"/></xsl:otherwise> |
| </xsl:choose> |
| </xsl:template> |
| |
| <xsl:template name="getParamBlock"> |
| <xsl:param name="style"/> |
| <xsl:if test="ancestor-or-self::wadl:*/wadl:param[@style=$style]"> |
| <div class="h7"><xsl:value-of select="$style"/> params</div> |
| <table> |
| <xsl:for-each select="ancestor-or-self::wadl:*/wadl:param[@style=$style]"> |
| <xsl:call-template name="getParams"/> |
| </xsl:for-each> |
| </table> |
| <p/> |
| </xsl:if> |
| </xsl:template> |
| |
| <xsl:template name="getParams"> |
| <tr> |
| <td style="font-weight: bold"><xsl:value-of select="@name"/></td> |
| <td> |
| <xsl:if test="not(@type) and not(@fixed)"> |
| unspecified type |
| </xsl:if> |
| <xsl:call-template name="getHyperlinkedElement"> |
| <xsl:with-param name="qname" select="@type"/> |
| </xsl:call-template> |
| <xsl:if test="@required = 'true'"><br/>(required)</xsl:if> |
| <xsl:if test="@repeating = 'true'"><br/>(repeating)</xsl:if> |
| <xsl:if test="@default"><br/>default: <tt><xsl:value-of select="@default"/></tt></xsl:if> |
| <xsl:if test="@type and @fixed"><br/></xsl:if> |
| <xsl:if test="@fixed">fixed: <tt><xsl:value-of select="@fixed"/></tt></xsl:if> |
| <xsl:if test="wadl:option"> |
| <br/>options: |
| <xsl:for-each select="wadl:option"> |
| <xsl:choose> |
| <xsl:when test="@mediaType"> |
| <br/><tt><xsl:value-of select="@value"/> (<xsl:value-of select="@mediaType"/>)</tt> |
| </xsl:when> |
| <xsl:otherwise> |
| <tt><xsl:value-of select="@value"/></tt> |
| <xsl:if test="position() != last()">, </xsl:if> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:for-each> |
| </xsl:if> |
| </td> |
| <xsl:if test="wadl:doc"> |
| <td><xsl:value-of select="wadl:doc"/></td> |
| </xsl:if> |
| </tr> |
| </xsl:template> |
| |
| <xsl:template name="getHyperlinkedElement"> |
| <xsl:param name="qname"/> |
| <xsl:variable name="prefix" select="substring-before($qname,':')"/> |
| <xsl:variable name="ns-uri" select="./namespace::*[name()=$prefix]"/> |
| <xsl:variable name="localname" select="substring-after($qname, ':')"/> |
| <xsl:choose> |
| <xsl:when test="$ns-uri='http://www.w3.org/2001/XMLSchema' or $ns-uri='http://www.w3.org/2001/XMLSchema-instance'"> |
| <a href="http://www.w3.org/TR/xmlschema-2/#{$localname}"><xsl:value-of select="$localname"/></a> |
| </xsl:when> |
| <xsl:when test="$ns-uri and starts-with($ns-uri, 'http://www.w3.org/XML/') = false()"> |
| <a href="{$ns-uri}#{$localname}"><xsl:value-of select="$localname"/></a> |
| </xsl:when> |
| <xsl:when test="$qname"> |
| <xsl:value-of select="$qname"/> |
| </xsl:when> |
| </xsl:choose> |
| </xsl:template> |
| |
| |
| |
| <xsl:template name="getRepresentations"> |
| <xsl:if test="wadl:representation"> |
| <div class="h7">representations</div> |
| <table> |
| <xsl:for-each select="wadl:representation"> |
| <tr> |
| <td style="font-weight: bold"><xsl:value-of select="@mediaType" /></td> |
| <xsl:choose> |
| <xsl:when test="@href or @element"> |
| <td> |
| <xsl:variable name="href" select="@href" /> |
| <xsl:choose> |
| <xsl:when test="@href"> |
| <xsl:variable name="localname" select="substring-after(@element, ':')"/> |
| <a href="{$href}"><xsl:value-of select="$localname" /></a> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:call-template name="getHyperlinkedElement"> |
| <xsl:with-param name="qname" select="@element" /> |
| </xsl:call-template> |
| </xsl:otherwise> |
| </xsl:choose> |
| </td> |
| </xsl:when> |
| <xsl:otherwise><td/></xsl:otherwise> |
| </xsl:choose> |
| |
| <xsl:if test="wadl:doc"> |
| <td> |
| <xsl:call-template name="getDoc"> |
| <xsl:with-param name="base" select="''" /> |
| </xsl:call-template> |
| </td> |
| </xsl:if> |
| </tr> |
| <xsl:call-template name="getRepresentationParamBlock"> |
| <xsl:with-param name="style" select="'template'" /> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getRepresentationParamBlock"> |
| <xsl:with-param name="style" select="'matrix'" /> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getRepresentationParamBlock"> |
| <xsl:with-param name="style" select="'header'" /> |
| </xsl:call-template> |
| |
| <xsl:call-template name="getRepresentationParamBlock"> |
| <xsl:with-param name="style" select="'query'" /> |
| </xsl:call-template> |
| </xsl:for-each> |
| </table> |
| </xsl:if> |
| </xsl:template><xsl:template name="getRepresentationParamBlock"> |
| <xsl:param name="style"/> |
| <xsl:if test="wadl:param[@style=$style]"> |
| <tr> |
| <td style="padding: 0em, 0em, 0em, 2em"> |
| <div class="h7"><xsl:value-of select="$style"/> params</div> |
| <table> |
| <xsl:for-each select="wadl:param[@style=$style]"> |
| <xsl:call-template name="getParams"/> |
| </xsl:for-each> |
| </table> |
| <p/> |
| </td> |
| </tr> |
| </xsl:if> |
| </xsl:template> |
| |
| <xsl:template name="getStyle"> |
| <style type="text/css"> |
| body { |
| font-family: sans-serif; |
| font-size: 0.85em; |
| margin: 2em 2em; |
| } |
| .methods { |
| margin-left: 2em; |
| margin-bottom: 2em; |
| } |
| .method { |
| background-color: #eef; |
| border: 1px solid #DDDDE6; |
| padding: .5em; |
| margin-bottom: 1em; |
| width: 50em |
| } |
| .methodNameTable { |
| width: 100%; |
| border: 0px; |
| border-bottom: 2px solid white; |
| font-size: 1.4em; |
| } |
| .methodNameTd { |
| background-color: #eef; |
| } |
| h1 { |
| font-size: 2m; |
| margin-bottom: 0em; |
| } |
| h2 { |
| border-bottom: 1px solid black; |
| margin-top: 1.5em; |
| margin-bottom: 0.5em; |
| font-size: 1.5em; |
| } |
| h3 { |
| color: #FF6633; |
| font-size: 1.35em; |
| margin-top: .5em; |
| margin-bottom: 0em; |
| } |
| h5 { |
| font-size: 1.2em; |
| color: #99a; |
| margin: 0.5em 0em 0.25em 0em; |
| } |
| h6 { |
| color: #700000; |
| font-size: 1em; |
| margin: 1em 0em 0em 0em; |
| } |
| .h7 { |
| margin-top: .75em; |
| font-size: 1em; |
| font-weight: bold; |
| font-style: italic; |
| color: blue; |
| } |
| .h8 { |
| margin-top: .75em; |
| font-size: 1em; |
| font-weight: bold; |
| font-style: italic; |
| color: black; |
| } |
| tt { |
| font-size: 1em; |
| } |
| table { |
| margin-bottom: 0.5em; |
| border: 1px solid #E0E0E0; |
| } |
| th { |
| text-align: left; |
| font-weight: normal; |
| font-size: 1em; |
| color: black; |
| background-color: #DDDDE6; |
| padding: 3px 6px; |
| border: 1px solid #B1B1B8; |
| } |
| td { |
| padding: 3px 6px; |
| vertical-align: top; |
| background-color: #F6F6FF; |
| font-size: 0.85em; |
| } |
| p { |
| margin-top: 0em; |
| margin-bottom: 0em; |
| } |
| td.summary { |
| background-color: white; |
| } |
| td.summarySeparator { |
| padding: 1px; |
| } |
| </style> |
| </xsl:template> |
| |
| <xsl:template name="getTitle"> |
| <xsl:choose> |
| <xsl:when test="wadl:doc/@title"> |
| <xsl:value-of select="wadl:doc/@title"/> |
| </xsl:when> |
| <xsl:otherwise> |
| Web Application |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:template> |
| |
| </xsl:stylesheet> |