WEBINAR:
On-Demand
Building the Right Environment to Support AI, Machine Learning and Deep Learning
New Operators, Keywords and Delimiters
In XPath 1.0 and XSLT 1.0 you couldn't use parentheses like this:
<xsl:for-each
select="(@name[.='Position'] |
@name[.='AccountsType'])">
Now you can. However, parentheses in XSLT 2.0 are really just a mechanism for making things more readable, not a way to manage nesting patterns as in object-oriented languages and arithmetic functions. Instead, they're used as either a basic way to group sequences in XPath expressions like I demonstrated at the beginning of this article, or to simply make your expressions a little more readable. Other changes are less cosmetic. In addition to the for keyword that you've already seen, XSLT 2.0 adds a number of other keywords and constructs that programmers coming from other backgrounds will find familiar, such as in, and even an
if-then-else construct:
<xsl:template match="someElement">
<xsl:apply-templates select="
if (eNode)
then document(eNode)
else document(strUrl)"/>
</xsl:template>
Grouping
One of the laments of anyone who has developed complex transformations is groupingan operation that should be fairly simple, but under XSLT 1.0 has been tedious at best and absolutely mind-numbing at worst.
Steve Muench's solution to grouping problems has become known as the Muenchian method. To aid in grouping, XSLT 2.0 introduces an additional value for evaluation context called the
current-group. This is a sequence of related items processed by the xsl:for-each-group element, and it is the key that unlocks that stubborn grouping door. The syntax for the element looks like this:
<!-- Category: instruction -->
<xsl:for-each-group
select = expression
group-by = expression
group-adjacent = expression
group-starting-with = pattern
group-ending-with = pattern
collation = { uri }
as = qname>
<!-- Content: (xsl:sort*,
content-constructor) -->
</xsl:for-each-group>
The for-each-group statement groups things the same way the Muenchian method does, but is less complex. For example, to group the costs of products in
Listing 1 by their names in a way that would match the name children of product elements, you'd first make a key:
<xsl:key name="costKey" match="price" use="name"/>
Then you'd access the key by calling the key function and cross reference it against the context node:
xsl:for-each
select="name[count(. | key('costKey',$name)[1]) = 1]"
You can see how this works in
Listing 5 at the end of this article, which shows the process in its entirety. I won't go into details about how it works here because XSLT 2.0 makes it irrelevant, and there's not enough space here for a primer on keys and grouping. If you need to learn more about keys and grouping for XSLT 1.0 projects, visit
Jeni Tennison's XSLT pages.
I'll discuss grouping in more detail later, but to see the difference, compare the grouping solution in
Listing 4 with that in
Listing 5 (the first is XSLT 2.0, the second is XSLT 1.0).