Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is easily solved with an <code>&lt;xsl:key&gt;</code>:</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" &gt; &lt;xsl:output method="text" /&gt; &lt;xsl:key name="kRole" match="ROLE" use="@name" /&gt; &lt;xsl:template match="ROLE"&gt; &lt;xsl:value-of select="concat(@name, ' ')" /&gt; &lt;xsl:value-of select="count( (. | preceding-sibling::ROLE)[ count(. | key('kRole', @name)[1]) = 1 ])" /&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>Output is as desired:</p> <pre><code>TESTER 1 PARENT1 2 PARENT1 2 PARENT1 2 PARENT2 3 PARENT2 3 PARENT3 4 PARENT4 5 TESTROLE 6 </code></pre> <p>Explanation of the XPath expression in the <code>&lt;xsl:value-of&gt;</code>:</p> <pre><code>count( # count the nodes: (. | preceding-sibling::ROLE) # union of this node and its predecessors [ # where... count( # the count of the union of... . | # this node and key('kRole', @name)[1] # the first node with the same @name ) = 1 # is 1 ] ) </code></pre> <p>This is the Muenchian method. Based on the fact that a node set cannot contain the same node twice, a union of two nodes has a node count of 1 if they are the same node. This way we are selecting the unique nodes from <code>(. | preceding-sibling::ROLE)</code> only.</p> <p>If there are more than one <code>&lt;ROLEACTIONINFO&gt;</code> elements in your document, there is a parent check missing. This is also easily achieved:</p> <pre><code> &lt;xsl:template match="ROLE"&gt; &lt;xsl:variable name="parentId" select="generate-id(..)" /&gt; &lt;xsl:value-of select="count( (. | preceding-sibling::ROLE)[ count(. | key('kRole', @name)[generate-id(..) = $parentId][1]) = 1 ])" /&gt; &lt;/xsl:template&gt; </code></pre> <p>Note that <code>[generate-id(..) = $parentId][1]</code> != <code>[1][generate-id(..) = $parentId]</code>. </p> <p>Order is important when chaining predicates. The former checks for parent node equality first and then takes the first unique node from the reduced set. This is what we want. </p> <p>The latter takes the first node from the set (all ROLE nodes with a given name throughout the document), takes the first one and then keeps or discards it based on parent equality. This is wrong.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload