XSL: How to Select Unique Nodes in a Node Set

I read on a different issue, talking about choosing unique nodes in a document (using the Muenchian method), but in my case I can’t use the keys (or I don’t know how), because I'm working on node and not on the document.

And the keys cannot be set to node-set. Basically I have a variable:

<xsl:variable name="limitedSet" select="
  $deviceInstanceNodeSet[position() &lt;= $tableMaxCol]" 
/>

which contains <deviceInstance>nodes that themselves contain elements <structure> a node set can be represented as follows:

<deviceInstance name="Demux TSchannel" deviceIndex="0">
  <structure name="DemuxTschannelCaps">
  </structure>
</deviceInstance>
<deviceInstance name="Demux TSchannel" deviceIndex="1">
  <structure name="DemuxTschannelCaps">
  </structure>
</deviceInstance>
<deviceInstance name="Demux TSchannel" deviceIndex="3">
  <structure name="otherCaps">
  </structure>
</deviceInstance>

And I do not know to select <structure>items that have only a different name. The selection in this example returns two items <structure>:

<structure name="DemuxTschannelCaps"></structure>
<structure name="otherCaps"></structure>

I tried

select="$limitedSet//structure[not(@name=preceding::structure/@name)]"  

but the previous axis goes throughout the document, not $limitedSet?

I'm stuck, can someone help me. Thanks.

+3
2
<xsl:variable name="structure" select="$limitedSet//structure" />

<xsl:for-each select="$structure">
  <xsl:variable name="name" select="@name" />
  <xsl:if test="generate-id() = generate-id($structure[@name = $name][1])">
    <xsl:copy-of select="." />
  </xsl:if>
</xsl:for-each>

:

<xsl:key name="kStructureByName" match="structure" use="@name" />
<!-- ... -->
<xsl:if test="generate-id() = generate-id(key('kStructureByName', $name)[1])">

:

<xsl:key name="kStructureByName" match="structure" use="
  concat(ancestor::device[1]/@id, ',', @name)
" />
<!-- ... -->
<xsl:variable name="name" select="concat(ancestor::device[1]/@id, ',', @name)" />
<xsl:if test="generate-id() = generate-id(key('kStructureByName', $name)[1])">
+3
select="$limitedSet//structure[not(@name=preceding::structure[count($limitedSet) = count($limitedSet | ..)]/@name)]"
+1

Source: https://habr.com/ru/post/1713365/


All Articles