xsl-list
[Top] [All Lists]

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

2012-03-01 13:12:26
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 Müller-Hillebrand
<mmh(_at_)cap-studio(_dot_)de> 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>
 <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(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--
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.

--~------------------------------------------------------------------
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(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


<Prev in Thread] Current Thread [Next in Thread>