[prev in list] [next in list] [prev in thread] [next in thread]
List: xsl-list
Subject: Re: [xsl] Finding triples with same/distinct attribute value
From: Michael Kay <mike () saxonica ! com>
Date: 2012-02-29 21:27:11
Message-ID: 4F4E982F.7070803 () saxonica ! com
[Download RAW message or body]
On 29/02/2012 20:26, Michael Müller-Hillebrand 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.
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
Saxonica
>
> - 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>
>
>
>
> --~------------------------------------------------------------------
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
> To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
> or e-mail:<mailto:xsl-list-unsubscribe@lists.mulberrytech.com>
> --~--
>
>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe@lists.mulberrytech.com>
--~--
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic