XSLT policy examples
Examples of the OpenAPI definitions of XSLT policies.
- Simple example with no context current payload
- Concatenation and transformation
- Obtain query parameter values and refer to context variables
- Return DataPower object name associated with a client TLS profile
Attention:
- The mechanisms described here for interacting with the API Connect context are intended for v5-compatible gateways and also to provide v5 compatibility for APIs created for the API Gateway. However, if you are writing an XSLT policy or user-defined policy for a new API Gateway API, use the mechanisms described in Using context variables in GatewayScript and XSLT policies with the DataPower API Gateway for better performance and long-term support. For API Gateway APIs, the v5-compatibility functions listed here are to be used for v5 migration only.
- 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 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: []
Return DataPower object name associated with a client TLS profile
The following example uses the
apim:getTLSProfileObjName
function to return the
DataPower object name associated with a specified client TLS profile.- xslt:
title: xslt
input: false
version: 2.0.0
source: >-
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:apim="http://www.ibm.com/apimanagement"
exclude-result-prefixes="dp apim"
extension-element-prefixes="dp"
version="1.0">
<!-- For apigw ... store:///dp/apim.custom.xsl -->
<!-- For v5/v5c ... local:///isp/policy/apim.custom.xsl -->
<!-- <xsl:import href="local:///isp/policy/apim.custom.xsl"/> -->
<xsl:import href="store:///dp/apim.custom.xsl"/>
<xsl:template match="/">
<xsl:variable name="httpHeaders">
<header name="Accept">application/xml</header>
</xsl:variable>
<!--
For v5, the name returned is client:<orgname>-my-test
For v5c, the name returned is client:<orgname>-my-testV1.0.0
For API Gateway, the name returned is client:<orgname>_<catalogname>_tlsp-my-testV1.0.0
-->
<xsl:variable name="tlsClientProfile" select="apim:getTLSProfileObjName('my-test')" />
<xsl:variable name="targetUrl" select="'https://127.0.0.1:6201/PingRequest'"/>
<dp:url-open target="{$targetUrl}" response="responsecode" timeout="20" http-headers="$httpHeaders" ssl-proxy="{$tlsClientProfile}"/>
</xsl:template>
</xsl:stylesheet>
For more examples of how to use XSLT to access and modify properties and context, see Implementation code examples and, if you are using the DataPower® API Gateway, Using context variables in GatewayScript and XSLT policies with the DataPower API Gateway.