XSLT policy examples
Examples of the OpenAPI (Swagger 2.0) definitions of XSLT policies.
- Simple example with no context current payload
- Concatenation and transformation
- Obtain query parameter values and refer to context variables
Note: The XML specification https://www.w3.org/TR/xml/ does not specify a preferred order for XML namespace (XMLNS)
attributes. Best practice is to not rely upon the sequence of XMLNS attributes if you write custom
parsing code.
Simple example with no context current payload
The following is an example of where the XSLT input document does not use the context current
payload (there is no
input):
- xslt:
title: example xslt
source: |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Hello>World!</Hello>
</xsl:template>
</xsl:stylesheet>
Concatenation and transformation
The following example shows a more complex XSLT transform source, where the stylesheet
concatenates two input strings and transforms the third input string to the IP address of the
client:
- xslt:
title: xslt
input: true
source: |
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xslt"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs4xs="http://www.w3.org/2001/XMLSchema"
xmlns:io="http://xformMessage"
xmlns:map="http://xformMessage/xform"
xmlns:msl="http://www.ibm.com/xmlmap"
exclude-result-prefixes="fn dp dp map xalan msl"
version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<!-- root wrapper template -->
<xsl:template match="/">
<msl:datamap>
<xsl:choose>
<xsl:when test="not(msl:datamap/dataObject[1]/@xsi:nil)">
<xsl:element name="dataObject">
<xsl:attribute name="xsi:type">
<xsl:value-of select="'io:data'"/>
</xsl:attribute>
<xsl:call-template name="map:xform">
<xsl:with-param name="data" select="msl:datamap/dataObject[1]"/>
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="dataObject">
<xsl:attribute name="xsi:type">
<xsl:value-of select="'io:data'"/>
</xsl:attribute>
<xsl:attribute name="xsi:nil">
<xsl:text>true</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</msl:datamap>
</xsl:template>
<!-- This rule represents a type mapping: "data" to "io:data". -->
<xsl:template name="map:xform">
<xsl:param name="data"/>
<!-- a simple data mapping: "$data/StringOne"(string) to "StringOne"(string) -->
<xsl:if test="$data/StringOne">
<StringOne>
<xsl:value-of select="concat($data/StringOne, $data/StringTwo)"/>
</StringOne>
</xsl:if>
<!-- a simple mapping with no associated source: to "StringTwo"(string) -->
<StringTwo>
<xsl:value-of select="dp:client-ip-addr()"/>
</StringTwo>
<!-- a simple data mapping: "$data/NumberOne"(int) to "NumberOne"(int) -->
<xsl:if test="$data/NumberOne">
<NumberOne>
<xsl:value-of select="$data/NumberOne"/>
</NumberOne>
</xsl:if>
<!-- a simple data mapping: "$data/NumberTwo"(int) to "NumberTwo"(int) -->
<xsl:if test="$data/NumberTwo">
<NumberTwo>
<xsl:value-of select="$data/NumberTwo"/>
</NumberTwo>
</xsl:if>
<!-- a simple data mapping: "$data/NumberThree"(int) to "NumberThree"(int) -->
<xsl:if test="$data/NumberThree">
<NumberThree>
<xsl:value-of select="$data/NumberThree"/>
</NumberThree>
</xsl:if>
</xsl:template>
<!-- ***************** Utility Templates ****************** -->
<!-- copy the namespace declarations from the source to the target -->
<xsl:template name="copyNamespaceDeclarations">
<xsl:param name="root"/>
<xsl:for-each select="$root/namespace::*[not(name() = '')]">
<xsl:copy/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Obtain query parameter values and refer to context variables
The following example shows a complete OpenAPI (Swagger 2.0) source file. The API
includes an XSLT
policy that obtains a query parameter value in XSLT, and also uses the
getvariable
method to retrieve the value of the context variable
request.headers.user-agent
.swagger: '2.0'
info:
x-ibm-name: xslt
title: xslt
version: 1.0.0
schemes:
- https
host: $(catalog.host)
basePath: /xslt
consumes:
- application/json
produces:
- application/json
securityDefinitions:
clientIdHeader:
type: apiKey
in: header
name: X-IBM-Client-Id
security:
- clientIdHeader: []
x-ibm-configuration:
testable: true
enforced: true
cors:
enabled: true
assembly:
execute:
- operation-switch:
title: operation-switch
case:
- operations:
- verb: get
path: /hello
execute:
- xslt:
title: SayHello
input: false
source: |
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:element name="APIc">
<xsl:text>Hello World!</xsl:text>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
- operations:
- verb: get
path: /getContextQueryVar
execute:
- xslt:
title: GetContextQueryVar
input: false
source: |
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:apim="http://www.ibm.com/apimanagement">
<xsl:import href="local:/isp/policy/apim.custom.xsl"/>
<xsl:template match="/">
<xsl:call-template name="apim:output">
<xsl:with-param name="mediaType" select="'application/xml'"/>
</xsl:call-template>
<APIC>
<xsl:element name="apim.getVariable">
<xsl:element name="useragent">
<xsl:value-of select="apim:getVariable('request.headers.user-agent')"/>
</xsl:element>
<xsl:element name="query">
<xsl:value-of select="apim:getVariable('request.querystring')"/>
</xsl:element>
</xsl:element>
</APIC>
</xsl:template>
</xsl:stylesheet>
- operations:
- verb: get
path: /getQuery
execute: []
otherwise:
- throw: null
title: handling unknown operation
name: Unsupported
catch:
- errors:
- Unsupported
execute:
- set-variable:
actions:
- set: message.body
value: '<error>Not Supported</error>'
phase: realized
paths:
/hello:
get:
responses:
'200':
description: 200 OK
/getContextQueryVar:
get:
responses:
'200':
description: 200 OK
definitions: {}
tags: []