Cheat sheet for XSL transformation
I'm really publishing this blog post for myself as a future reference. :)
This .xsl
file (aka XSL transformation file) contains perhaps 90% of everything I generally use in my Oracle SOA development projects.
Here is the file in its entirety (I'll break it down further below):
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:ns0="http://revelationtech.com/JobCodes"
xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator"
xmlns:oracle-xsl-mapper="http://www.oracle.com/xsl/mapper/schemas"
xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"
xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.MediatorExtnFunction"
xmlns:oraxsl="http://www.oracle.com/XSL/Transform/java"
xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
exclude-result-prefixes="oracle-xsl-mapper xsi xsd xsl ns0 socket dvm mhdr oraxsl oraext xp20 xref"
xmlns:plt="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:tns="http://xmlns.oracle.com/pcbpel/adapter/file/Application/Project/FileRead"
xmlns:pc="http://xmlns.oracle.com/pcbpel/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:strClass="http://www.oracle.com/XSL/Transform/java/java.lang.String"
xmlns:jca="http://xmlns.oracle.com/pcbpel/wsdl/jca/">
<oracle-xsl-mapper:schema>
<oracle-xsl-mapper:mapSources>
<oracle-xsl-mapper:source type="WSDL">
<oracle-xsl-mapper:schema location="../WSDLs/FileRead.wsdl"/>
<oracle-xsl-mapper:rootElement name="jobcodes" namespace="http://revelationtech.com/JobCodes"/>
</oracle-xsl-mapper:source>
</oracle-xsl-mapper:mapSources>
<oracle-xsl-mapper:mapTargets>
<oracle-xsl-mapper:target type="WSDL">
<oracle-xsl-mapper:schema location="../WSDLs/FileRead.wsdl"/>
<oracle-xsl-mapper:rootElement name="jobcodesconcat" namespace="http://revelationtech.com/TargetInfo"/>
</oracle-xsl-mapper:target>
</oracle-xsl-mapper:mapTargets>
</oracle-xsl-mapper:schema>
<xsl:template match="/">
<ns0:targetinfo>
<xsl:for-each select="/ns0:jobcodes/ns0:jobcode">
<xsl:variable name="i" select="position()"/>
<xsl:value-of select="strClass:replaceAll(concat (/targetinfo, '"', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Active, '";"', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Code, '";"', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Name, '" '), '&', '%26amp;')"/>
</xsl:for-each>
</ns0:targetinfo>
</xsl:template>
</xsl:stylesheet>
I'll go through each of the various areas, but it'll be a bit modified for clarity.
Selecting
This simply copies an element from the source to the target (the target being /ns0:targetinfo
).
<ns0:targetinfo>
<xsl:value-of select="/ns0:jobcodes/ns0:jobcode/ns0:Active"/>
</ns0:targetinfo>
Looping
This loops through the source array, and references the array position jobcode[$i]
in each iteration. You would need to create a counter $i
.
<ns0:targetinfo>
<xsl:for-each select="/ns0:jobcodes/ns0:jobcode">
<xsl:variable name="i" select="position()"/>
<xsl:value-of select="/ns0:jobcodes/ns0:jobcode[$i]/ns0:Active"/>
</xsl:for-each>
</ns0:targetinfo>
Using Quotes
This concatenates a double quote in the beginning and end of the source element before copying it to the target element. A double quote is "
and a single quote is '
.
<ns0:targetinfo>
<xsl:value-of select="concat('"', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Active, '"')"/>
</ns0:targetinfo>
Replacing & with &
Many target systems don't like the &
sign, and require it to be replaced with &
. It looks weird here, but do to this you actually replace &
with %26amp;
.
<ns0:targetinfo>
<xsl:value-of select="strClass:replaceAll(/ns0:jobcodes/ns0:jobcode[$i]/ns0:Active, '&', '%26amp;')"/>
</ns0:targetinfo>
If using the strClass
namespace, it has to be referenced in the stylesheet above as:
xmlns:strClass="http://www.oracle.com/XSL/Transform/java/java.lang.String"
Adding a Line Break
If you want to add a line break after the element, you will need to manually concatenate the characters
and &$10;
.
<ns0:targetinfo>
<xsl:value-of select="concat (/ns0:jobcodes/ns0:jobcode/ns0:Active, ' ')"/>
</ns0:targetinfo>
Concatenating Source Array to a Single Target Element
This loops through all the source elements, and concatenates them all into a single target element that is comma delimited; the target element being /targetinfo
.
<ns0:targetinfo>
<xsl:for-each select="/ns0:jobcodes/ns0:jobcode">
<xsl:variable name="i" select="position()"/>
<xsl:value-of select="strClass:replaceAll(concat (/targetinfo, /ns0:jobcodes/ns0:jobcode[$i]/ns0:Active, ',', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Code, ',', /ns0:jobcodes/ns0:jobcode[$i]/ns0:Name)"/>
</xsl:for-each>
</ns0:targetinfo>