Re: [xsl] Finding triples with same/distinct attribute value

Subject: Re: [xsl] Finding triples with same/distinct attribute value
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Thu, 1 Mar 2012 11:11:52 -0800
This task can be made somewhat easier by using the index-of() function
-- it produces the positions for you.


Cheers,
Dimitre

On Wed, Feb 29, 2012 at 12:26 PM, Michael MC<ller-Hillebrand
<mmh@xxxxxxxxxxxxx> wrote:
>
> 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>
> B <pot a="3" />
> B <pot a="3" />
> B <pot a="3" />
> B <pot a="1" />
> B <pot a="1" />
> B <pot a="1" />
> B <pot a="1" />
> B <pot a="1" />
> B <pot a="1" />
> B <pot a="3" />
> B <pot a="2" />
> B <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"
> B xmlns:xs="http://www.w3.org/2001/XMLSchema";
> B xmlns:my="http://my";
> B exclude-result-prefixes="xs my"
> B >
> B <xsl:output indent="yes"/>
>
> B <xsl:template match="pots">
> B <result>
> B  <xsl:sequence select="my:triples(*)" />
> B </result>
> B </xsl:template>
>
> B <xsl:function name="my:triples" as="node()*">
> B <xsl:param name="nodes" as="node()+"/>
>
> B <!-- common values -->
> B <xsl:for-each select="$nodes">
> B  <xsl:variable name="t1" select="."/>
> B  <xsl:for-each select="$t1/following-sibling::*[@a eq $t1/@a]">
> B  B <xsl:variable name="t2" select="."/>
> B  B <xsl:for-each select="$t2/following-sibling::*[@a eq $t1/@a]">
> B  B  <triple>
> B  B  B <xsl:value-of select="string-join((my:pos($nodes, $t1),
> my:pos($nodes, $t2), my:pos($nodes, .)), ' ')" />
> B  B  </triple>
> B  B </xsl:for-each>
> B  </xsl:for-each>
> B </xsl:for-each>
>
> B <!-- distinct values -->
> B <xsl:for-each select="$nodes">
> B  <xsl:variable name="t1" select="."/>
> B  <xsl:for-each select="$t1/following-sibling::*[@a ne $t1/@a]">
> B  B <xsl:variable name="t2" select="."/>
> B  B <xsl:for-each select="$t2/following-sibling::*[@a ne $t1/@a and @a ne
> $t2/@a]">
> B  B  <triple>
> B  B  B <xsl:value-of select="string-join((my:pos($nodes, $t1),
> my:pos($nodes, $t2), my:pos($nodes, .)), ' ')" />
> B  B  </triple>
> B  B </xsl:for-each>
> B  </xsl:for-each>
> B </xsl:for-each>
>
> B </xsl:function>
>
> B <xsl:function name="my:pos" as="xs:string">
> B <xsl:param name="nodes" as="node()+"/>
> B <xsl:param name="node" as="node()"/>
> B <xsl:value-of select="count($nodes[$node >> .]) + 1" />
> B </xsl:function>
>
> </xsl:transform>
>



--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.

Current Thread