WEBINAR:
On-Demand
Application Security Testing: An Integral Part of DevOps
Extending XSLT
Sometimes XSLT turns to be too lexically poor to do complex transformations. Two viable options then exist:
- Chain the execution of XSLTs instead of trying to do everything in one pass.
- Use common extension functions from the EXSLT package.
Chaining XSLT Execution
Contrary to what one might think, chaining XSLT stylesheetsusing the output of one stylesheet transformation as the input for the next stylesheet in the chaindoes not add much overhead if done in a proper way. Although nearly all XSLT processors reconstruct the structure of the input document in memory for each pass, that process is not equivalent to the reconstruction of a DOM tree. Most XSLT processors use an internal format that may be a lot faster. In fact, a number of small XSLT stylesheets chained together can actually boost performance as compared to a single complex stylesheet.
Using Common Extension Functions
There is an effort to provide a more or less common set of extensions to XSLT with the corresponding reference implementations. Some of these functions already exist in various XSLT processors under different names.
The most notable function is node-set. It allows the conversion of
result tree fragments into
node-sets. If you create a variable with a
select statement, it returns a node-set:
<xsl:variable name="foo" select="/"/>
In contrast, if you create a variable with an embedded statement, it returns a result tree fragment:
<xsl:variable name="foo">
<xsl:copy-of select="/">
</xsl:variable>
Because XSLT allows more operations on node-sets, it is wise to use the
select statement when possible instead of embedded statements. Otherwise, the node-set extension function would come to the rescue.
The node-set extension function exists for several processors:
4XSLT,
Xalan-J,
Saxon,
jd.xslt, and
libxslt, and you make it accessible to your stylesheets by including the namespace
http://exslt.org/common.
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
version="1.0">
<xsl:variable name="all">
<xsl:copy-of select="child::*[1]">
</xsl:variable>
<xsl:template select="/">
<root>
<xsl:copy-of select="ext:node-set($all)">
</root>
</xsl:template>
</xsl:stylesheet>
As a sign of EXSLT's popularity, even Microsoft supports some of the EXSLT functions. However, Microsoft uses a different namespace:
urn:schemas-microsoft-com:xslt.
Overall, as an occasional XSLT developer, try to keep the advantages of functional and flow-driven programming in mindand be wary of falling into the trap of trying to use the procedural or imperative programming techniques that you commonly use in standard programming languages.