I have a situation where I think I need to daisy chain my xslt transformation (i.e. that output of one xslt transform being input into another). The first transform is rather complex with lots of xsl:choice and ancestor xpaths. My thought is to transform the xml into xml that can then be easily transformed to html.
My question is 'Is this standard practice or am I missing something?'
Thanks in advance.
Stephen
The XSLT processor operates on two inputs: the XML document to transform, and the XSLT stylesheet that is used to apply transformations on the XML.
XSL Transformation (XSLT)XSLT is designed to be used as part of XSL. In addition to XSLT, XSL includes an XML vocabulary for specifying formatting. XSL specifies the styling of an XML document by using XSLT to describe how the document is transformed into another XML document that uses the formatting vocabulary.
JavaScript can run XSLT transformations through the XSLTProcessor object. Once instantiated, an XSLTProcessor has an XSLTProcessor. importStylesheet() method that takes as an argument the XSLT stylesheet to be used in the transformation. The stylesheet has to be passed in as an XML document, which means that the .
The Extensible Stylesheet Language Transformation (XSLT) standard specifies a language definition for XML data transformations. XSLT is used to transform XML documents into XHTML documents, or into other XML documents.
Performing a chain of transformations is used quite often in XSLT applications, though doing this entirely in XSLT 1.0 requires the use of the vendor-specific xxx:node-set()
function. In XSLT 2.0 no such extension is needed as the infamous RTF datatype is eliminated there.
Here is an example (too-simple to be meaningful, but illustrating completely how this is done):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*/*"/>
</xsl:variable>
<xsl:variable name="vPass1"
select="ext:node-set($vrtfPass1)"/>
<xsl:apply-templates mode="pass2"
select="$vPass1/*"/>
</xsl:template>
<xsl:template match="num[. mod 2 = 1]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="num" mode="pass2">
<xsl:copy>
<xsl:value-of select=". *2"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
the wanted, correct result is produced:
<num>2</num>
<num>6</num>
<num>10</num>
<num>14</num>
<num>18</num>
Explanation:
In the first step the XML document is transformed and the result is defined as the value of the variable $vrtfPass1
. This copies only the num
elements that have odd value (not even).
The $vrtfPass1
variable, being of type RTF, is not directly usable for XPath expressions so we convert it to a normal tree, using the EXSLT (implemented by most XSLT 1.0 processors) function ext:node-set
and defining another variable -- $vPass1
whose value is this tree.
We now perform the second transformation in our chain of transformations -- on the result of the first transformation, that is kept as the value of the variable $vPass1
. Not to mess with the first-pass template, we specify that the new processing should be in a named mode, called "pass2". In this mode the value of any num
element is multiplied by two.
XSLT 2.0 solution (no RTFs):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vPass1" >
<xsl:apply-templates select="/*/*"/>
</xsl:variable>
<xsl:apply-templates mode="pass2"
select="$vPass1/*"/>
</xsl:template>
<xsl:template match="num[. mod 2 = 1]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="num" mode="pass2">
<xsl:copy>
<xsl:value-of select=". *2"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With