|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: Tricky inclusion match
Karl, here's an XSLT 1.0 solution:
My basis for this are templates from Sal Mangano's "XSLT Cookbook"; please search this list for other times I've referenced this resource, including mentioning from where to download its code. My approach is to hold the <colors> element in a variable, and then to compare its children against those of each <picture> element, in an "intersection" operation. If we have 2 or more intersections, print: Regards, --A colors.xsl ====== <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vset="http:/www.ora.com/XSLTCookbook/namespaces/vset" extension-element-prefixes="vset"> <xsl:import href="vset.ops.xsl"/> <xsl:output method="text" />
<xsl:if test="string-length($matchcount) >= 2">
<xsl:text>picture sample #</xsl:text>
<xsl:value-of select="@sample"/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:call-template name="vset:intersection">
<xsl:with-param name="nodes1" select="$node1//*"/>
<xsl:with-param name="nodes2" select="$node2//*"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="node( ) | @*" mode="vset:element-equality"> <xsl:param name="other"/> <xsl:if test="local-name(.) = local-name($other) and ./text() = $other/text()"> <xsl:value-of select="true()"/> </xsl:if> </xsl:template> </xsl:stylesheet> vset.ops.xsl ====== <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vset="http:/www.ora.com/XSLTCookbook/namespaces/vset"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- The default implementation of element equality. Override in the importing stylesheet as neccessary. --> <xsl:template match="node( ) | @*" mode="vset:element-equality"> <xsl:param name="other"/> <xsl:if test=". = $other"> <xsl:value-of select="true( )"/> </xsl:if> </xsl:template> <!-- 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> <!-- Compute the union of two sets using "by value" equality. --> <xsl:template name="vset:union"> <xsl:param name="nodes1" select="/.." /> <xsl:param name="nodes2" select="/.." /> <!-- for internal use --> <xsl:param name="nodes" select="$nodes1 | $nodes2" /> <xsl:param name="union" select="/.." /> <xsl:choose> <xsl:when test="$nodes"> <xsl:variable name="test"> <xsl:apply-templates select="$union" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes[1]" /> </xsl:apply-templates> </xsl:variable> <xsl:call-template name="vset:union"> <xsl:with-param name="nodes" select="$nodes[position( ) > 1]" /> <xsl:with-param name="union" select="$union | $nodes[1][not(string($test))]" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="$union" mode="vset:union" /> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Return a copy of union by default. Override in importing stylesheet to recieve reults as a "callback"--> <xsl:template match="/ | node( ) | @*" mode="vset:union"> <xsl:copy-of select="."/> </xsl:template>
<xsl:choose> <xsl:when test="not($nodes1)"> <xsl:apply-templates select="$intersect" mode="vset:intersection"/> </xsl:when> <xsl:when test="not($nodes2)"> <xsl:apply-templates select="$intersect" mode="vset:intersection"/> </xsl:when> <xsl:otherwise> <xsl:variable name="test1"> <xsl:apply-templates select="$nodes2" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:variable name="test2"> <xsl:apply-templates select="$intersect" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:choose> <xsl:when test="string($test1) and not(string($test2))"> <xsl:call-template name="vset:intersection"> <xsl:with-param name="nodes1" select="$nodes1[position( ) > 1]"/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="intersect" select="$intersect | $nodes1[1]"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="vset:intersection"> <xsl:with-param name="nodes1" select="$nodes1[position( ) > 1]"/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="intersect" select="$intersect"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Return a copy of intersection by default. Override in importing stylesheet to recieve 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="/.."/> <xsl:choose> <xsl:when test="not($nodes1)"> <xsl:apply-templates select="$difference" mode="vset:difference"/> </xsl:when> <xsl:when test="not($nodes2)"> <xsl:apply-templates select="$nodes1" mode="vset:difference"/> </xsl:when> <xsl:otherwise> <xsl:variable name="test1"> <xsl:apply-templates select="$nodes2" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:variable name="test2"> <xsl:apply-templates select="$difference" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:choose> <xsl:when test="string($test1) or string($test2)"> <xsl:call-template name="vset:difference"> <xsl:with-param name="nodes1" select="$nodes1[position( ) > 1]"/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="difference" select="$difference"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="vset:difference"> <xsl:with-param name="nodes1" select="$nodes1[position( ) > 1]"/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="difference" select="$difference | $nodes1[1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Computes the differnce between two sets (node1 - nodes2) using "by value" equality. "Short-circuit"-s processing at the first difference-node. --> <xsl:template name="vset:difference-short-circuit"> <xsl:param name="nodes1" select="/.."/> <xsl:param name="nodes2" select="/.."/> <!-- For internal use --> <xsl:param name="difference" select="/.."/> <xsl:choose> <xsl:when test="not($nodes1)"> <xsl:apply-templates select="$difference" mode="vset:difference"/> </xsl:when> <xsl:when test="not($nodes2)"> <xsl:apply-templates select="$nodes1" mode="vset:difference"/> </xsl:when> <xsl:otherwise> <xsl:variable name="test1"> <xsl:apply-templates select="$nodes2" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:variable name="test2"> <xsl:apply-templates select="$difference" mode="vset:member-of"> <xsl:with-param name="elem" select="$nodes1[1]"/> </xsl:apply-templates> </xsl:variable> <xsl:choose> <xsl:when test="string($test1) or string($test2)"> <xsl:call-template name="vset:difference-short-circuit"> <xsl:with-param name="nodes1" select="$nodes1[position( ) > 1]"/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="difference" select="$difference"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="vset:difference-short-circuit"> <xsl:with-param name="nodes1" select="/.."/> <xsl:with-param name="nodes2" select="$nodes2"/> <xsl:with-param name="difference" select="$difference | $nodes1[1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Return a copy of difference by default. Override in importing stylesheet to recieve results as a "callback"--> <xsl:template match="/ | node( ) | @*" mode="vset:difference"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet> From: Karl Stubsjoen <kstubs@xxxxxxxxx> Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Tricky inclusion match Date: Tue, 29 Mar 2005 07:55:43 -0700 _________________________________________________________________ Dont just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








