XSL:如何选择节点集中的唯一节点

时间:2009-07-23 16:46:17

标签: xslt xpath

我一直在阅读关于在文档中选择唯一节点的不同问题(使用Muenchian方法),但在我的情况下我不能使用密钥(或者我不知道如何),因为我正在处理节点集和不在文件上。

无法在节点集上设置密钥。基本上我有一个变量:

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

包含<deviceInstance>个节点,这些节点本身包含<structure>个元素 节点集可以这样表示:

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

我不知道选择只有不同名称的<structure>元素。在此示例中,select将返回两个<structure>元素,即:

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

我试过了

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

但前面的轴沿着文档而不是$limitedSet

我被困住了,有人可以帮助我。谢谢。

2 个答案:

答案 0 :(得分:3)

<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])">

答案 1 :(得分:1)

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