Subject: Re: [xsl] Finding triples with same/distinct attribute value From: Michael Müller-Hillebrand <mmh@xxxxxxxxxxxxx> Date: Thu, 1 Mar 2012 20:02:08 +0100 |
Am 29.02.2012 um 22:27 schrieb Michael Kay: >> 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. > I think you need to state the requirement more clearly. Reverse-engineering it from your code isn't that easy. Is your definition of a "triple" this: "a sequence of three distinct <pot> elements, not necessarily adjacent, but in document order"? Michael Kay, Thanks for reminding me how important precision is when dealing with logic. A triple is a sequence of any three distinct <pot> elements. The result does not have to be in document order. But because the nodes have no id, my stylesheet reports their position in the parent element (using a complicated method instead of position() which features the cool >> operator). - Michael M|ller-Hillebrand >> 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] faster complicated counti, Syd Bauman | Thread | Re: [xsl] Finding triples with same, Dimitre Novatchev |
Re: [xsl] faster complicated counti, Syd Bauman | Date | Re: [xsl] Finding triples with same, Dimitre Novatchev |
Month |