Performing Set Operations on Node Sets Using Value Semantics continued
The following stylesheet provides a reusable implementation of union, intersection, and set difference based on value semantics. The idea is that a stylesheet importing this one will override the template whosemode="vset:element-equality". This allows the importing stylesheet to define whatever equality semantics make sense for the given input:
<!-- The default set membership test uses element equality. You will rarely need to override this in the importing stylesheet. --> <xsl:template match="node() | @*" mode="vset:member-of"> <xsl:param name="elem"/> <xsl:variable name="member-of"> <xsl:for-each select="."> <xsl:apply-templates select="." mode="vset:element-equality"> <xsl:with-param name="other" select="$elem"/> </xsl:apply-templates> </xsl:for-each> </xsl:variable> <xsl:value-of select="string($member-of)"/> </xsl:template>
<!-- Return a copy of union by default. Override in importing stylesheet to receive reults as a "callback"--> <xsl:template match="/ | node() | @*" mode="vset:union"> <xsl:copy-of select="."/> </xsl:template>
<!-- Compute the intersection of two sets using "by value" equality. --> <xsl:template name="vset:intersection"> <xsl:param name="nodes1" select="/.."/> <xsl:param name="nodes2" select="/.."/> <!-- For internal use --> <xsl:param name="intersect" select="/.."/>
<!-- Return a copy of intersection by default. Override in importing stylesheet to receive results as a "callback"--> <xsl:template match="/ | node() | @*" mode="vset:intersection"> <xsl:copy-of select="."/> </xsl:template>
<!-- Compute the differnce between two sets (node1 - nodes2) using "by value" equality. --> <xsl:template name="vset:difference"> <xsl:param name="nodes1" select="/.."/> <xsl:param name="nodes2" select="/.."/> <!-- For internal use --> <xsl:param name="difference" select="/.."/>
<!-- Return a copy of difference by default. Override in importing stylesheet to receive results as a "callback"--> <xsl:template match="/ | node() | @*" mode="vset:difference"> <xsl:copy-of select="."/> </xsl:template>