[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Finding triples with same/distinct attribute value
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>
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|