Performing Set Operations When Querying XML - XSLT 2.0 Enhancements
(Page 3 of 4 )
The main enhancement of XSLT 2.0 is to take advantage of the availability of first-class functions and sequences. This eliminates the need for recursion, the call-back trick, and leads to cleaner definitions and usage. The functions vset:element-equality and vset:member-ofcan still be overridden in importing stylesheets to customize behavior.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"
xmlns:xs="http://www.w3.org/2001/ XMLSchema"
xmlns:vset="http:/www.ora.com/XSLTCookbook/ namespaces/vset">
<!-- The default implementation of element equality. Override in the importing
stylesheet as necessary. -->
<xsl:function name="vset:element-equality" as="xs:boolean">
<xsl:param name="item1" as="item()?"/>
<xsl:param name="item2" as="item()?"/>
<xsl:sequence select="$item1 = $item2"/>
</xsl:function>
<!-- The default set membership test uses element equality. You will rarely need to
override this in the importing stylesheet. -->
<xsl:function name="vset:member-of" as="xs:boolean">
<xsl:param name="set" as="item()*"/>
<xsl:param name="elem" as="item()"/>
<xsl:variable name="member-of" as="xs:boolean*"
select="for $test in $set
return if (vset:element-equality($test, $elem))
then true() else ()"/>
<xsl:sequence select="not(empty($member-of))"/>
</xsl:function>
<!-- Compute the union of two sets using "by value" equality. -->
<xsl:function name="vset:union" as="item()*">
<xsl:param name="nodes1" as="item()*" />
<xsl:param name="nodes2" as="item()*" />
<xsl:sequence select="$nodes1, for $test in $nodes2
return if (vset:member-of($nodes1,$test))
then () else $test"/>
</xsl:function>
<!-- Compute the intersection of two sets using "by value" equality. -->
<xsl:function name="vset:intersection" as="item()*">
<xsl:param name="nodes1" as="item()*" />
<xsl:param name="nodes2" as="item()*" />
<xsl:sequence select="for $test in $nodes1
return if (vset:member-of($nodes2,$test))
then $test else ()"/>
</xsl:function>
<!-- Compute the difference between two sets (node1 - nodes2) using "by value"
equality. -->
<xsl:function name="vset:difference" as="item()*">
<xsl:param name="nodes1" as="item()*" />
<xsl:param name="nodes2" as="item()*" />
<xsl:sequence select="for $test in $nodes1 return if (vset:member-of($nodes2,$test))
then () else $test"/>
</xsl:function>
</xsl:stylesheet>
Next: Equality in Programming >>
More XML Tutorials Articles
More By O'Reilly Media
|
This article is excerpted from chapter nine of the XSLT Cookbook, Second Edition, written by Sal Mangano (O'Reilly; ISBN: 0596009747). Check it out today at your favorite bookstore. Buy this book now.
|
|