Subject: [xsl] Finding triples with same/distinct attribute value From: Michael Müller-Hillebrand <mmh@xxxxxxxxxxxxx> Date: Wed, 29 Feb 2012 21:26:48 +0100 |
Dear gurus, I have a solution but I am eager to learn whether there is a better method to solve the problem. There is a number of elements with an attribute. The task is to find every triple of elements with the same attribute value or with distinct attribute values. I solved it using xsl:for-each loops but feel like having missed some XPath 2 features. I am looking forward to your comments. - Michael PS: I get a result of 60 triples with the sample file. Input: <pots> <pot a="3" /> <pot a="3" /> <pot a="3" /> <pot a="1" /> <pot a="1" /> <pot a="1" /> <pot a="1" /> <pot a="1" /> <pot a="1" /> <pot a="3" /> <pot a="2" /> <pot a="3" /> </pots> XSL: <?xml version="1.0" encoding="UTF-8"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="http://my" exclude-result-prefixes="xs my" > <xsl:output indent="yes"/> <xsl:template match="pots"> <result> <xsl:sequence select="my:triples(*)" /> </result> </xsl:template> <xsl:function name="my:triples" as="node()*"> <xsl:param name="nodes" as="node()+"/> <!-- common values --> <xsl:for-each select="$nodes"> <xsl:variable name="t1" select="."/> <xsl:for-each select="$t1/following-sibling::*[@a eq $t1/@a]"> <xsl:variable name="t2" select="."/> <xsl:for-each select="$t2/following-sibling::*[@a eq $t1/@a]"> <triple> <xsl:value-of select="string-join((my:pos($nodes, $t1), my:pos($nodes, $t2), my:pos($nodes, .)), ' ')" /> </triple> </xsl:for-each> </xsl:for-each> </xsl:for-each> <!-- distinct values --> <xsl:for-each select="$nodes"> <xsl:variable name="t1" select="."/> <xsl:for-each select="$t1/following-sibling::*[@a ne $t1/@a]"> <xsl:variable name="t2" select="."/> <xsl:for-each select="$t2/following-sibling::*[@a ne $t1/@a and @a ne $t2/@a]"> <triple> <xsl:value-of select="string-join((my:pos($nodes, $t1), my:pos($nodes, $t2), my:pos($nodes, .)), ' ')" /> </triple> </xsl:for-each> </xsl:for-each> </xsl:for-each> </xsl:function> <xsl:function name="my:pos" as="xs:string"> <xsl:param name="nodes" as="node()+"/> <xsl:param name="node" as="node()"/> <xsl:value-of select="count($nodes[$node >> .]) + 1" /> </xsl:function> </xsl:transform>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Namespaces on attributes, Wendell Piez | Thread | Re: [xsl] Finding triples with same, Michael Kay |
Re: [xsl] Mixed content, separation, Wendell Piez | Date | Re: [xsl] faster complicated counti, Liam R E Quin |
Month |