[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