Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt XSL:如何在节点集中选择唯一的节点_Xslt_Xpath - Fatal编程技术网

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

Xslt XSL:如何在节点集中选择唯一的节点,xslt,xpath,Xslt,Xpath,我一直在阅读关于在文档中选择唯一节点的不同问题(使用Muenchian方法),但在我的情况下,我不能使用键(或者我不知道如何使用键),因为我在处理节点集,而不是文档 不能在节点集上设置和键。基本上我有一个变量: <xsl:variable name="limitedSet" select=" $deviceInstanceNodeSet[position() &lt;= $tableMaxCol]" /> 但是前面的轴沿着文档,而不是$limitedSet 我卡住了,

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

不能在节点集上设置和键。基本上我有一个变量:

<xsl:variable name="limitedSet" select="
  $deviceInstanceNodeSet[position() &lt;= $tableMaxCol]" 
/>
但是前面的轴沿着文档,而不是
$limitedSet

我卡住了,有人能帮帮我吗。谢谢。


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


我认为,正如我所说,axi应用程序不会出现在所有文档上,而不是节点集上。此外,据我所知,前面的兄弟姐妹不会去结构所在的另一个设备。不过还是要感谢您的尝试。
前面的
后面的
轴适用于所有文档,但是
前面的同级
后面的同级
仅适用于具有相同父节点的节点。但是,您没有考虑其他
deviceInstance
元素中的节点,这是正确的。请尝试更新版本。我不得不想出一个方法来测试
$limitedSet
.houaou中是否存在节点。这是一个令人讨厌的方法,也是一个聪明的方法。很好的输入,但我更喜欢Tomalak解决方案,因为我有一个非常大的文件(30400行),它看起来更有效,因为它仅限于limitedSet,而您的解决方案必须查找文档中前面的所有节点。这实际上是我在xsl的其他地方遇到的问题,前面的axis非常昂贵。这是一个很好的答案,节省了我的时间,非常感谢您的快速回复。这个网站是伟大的,我会注册给这个答案排名。太谢谢你了。SeB.我考虑过你的关键建议,但这不起作用,因为我需要在多个设备中使用一个结构,而你的建议只适用于一个设备。@SeB:不确定你的意思-我的建议(至少是关键的第二个版本)适用于多个设备。当然,您必须根据实际的XML调整“use”表达式,但这不是不可能的。基本上,在第二种方法中不使用limitedSet。该测试仅适用于给定设备中的第一个结构,而不适用于多个设备的有限集合。第一个解决方案在所有limitedSet中查找第一个结构;不适用于文档中的所有节点。
<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])">
select="$limitedSet//structure[not(@name=preceding::structure[count($limitedSet) = count($limitedSet | ..)]/@name)]"