我觉得,这是一个基本的XSLT问题。根据我的理解,节点集本身就是数据结构。从node-set()我无法导航到集合之外的任何节点。即我无法到达父母,xml的开头及其兄弟姐妹。这是对的吗?
或
有没有办法获得node-set()
的父级代码
<neighbourhood>
<parent name = "xyz">
<child address=10> a </child>
<child address=10> b </child>
<child address=15> c </child>
</parent>
</neighbourhood>
我有一组子节点。我需要消除具有重复“地址”的节点。 可以有n个'parent'和m个'child',并且'child'可以有祖父节点。
最好的和合乎逻辑的方式可能是由每个父母去处理他们的孩子。但是,它是一个现有的代码库,这是一个过于简单的例子。我不想通过触摸调用函数和其他模板来破解太多东西。
所以,我的问题是我是否可以通过我所拥有的'子'节点集来获取'父级'
感谢您的所有回复
答案 0 :(得分:3)
node-set()是否有祖先节点?
node-set()
是(扩展)函数 - 不是节点。函数不能具有祖先,因为它不是节点。
我认为问题中"node-set()"
表示xxx:node-set()
函数返回的值(前缀&#34; xxx&#34;绑定到特定于供应商的值)命名空间)。如果是这样,这是通缉答案:
根据定义,xxx:node-set()
函数会返回临时树的 document-node()
(在XPath 1.0中也称为root-node
),这是通过转换获得的RTF(结果树片段),作为此函数的唯一参数传递。
按定义,文档节点位于文档层次结构的顶部,是XML文档中唯一没有父文档的节点。
因此,被调用的xxx:node-set()
函数返回的节点没有任何祖先。
从node-set()我无法导航到集合之外的任何节点。即我无法到达父母,xml的开头及其兄弟姐妹。这是对的吗?
是的,不调用另一个从另一个文档返回节点的函数(例如标准XPath函数id()
或标准XSLT函数document()
),或者引用变量/参数,它不是只能通过使用XPath位置步骤从其他文档导航到节点。
或
有没有办法获得node-set()
的父级
不,xxx:node-set()
函数返回的节点是文档节点,文档节点没有父节点(或任何其他祖先节点)。
答案 1 :(得分:2)
不要混淆节点集和node-set()
s。
这是什么意思?嗯,节点集是一组节点。在正常的,未扩展的XSLT 1.0中,这意味着从输入文档中选择节点。如果我这样做:
<!-- a node set -->
<xsl:variable name="my-node-set"
select="/indoc/level1/level2"/>
变量$my-node-set
包含一组level2
个节点,但这些节点仍然存在于输入文档中。如果我随后这样做for-each
:
<nodeset-from-indoc>
<xsl:for-each select="$my-node-set/level3">
<parent>
<xsl:value-of select="local-name(..)"/>
</parent>
<grandparent>
<xsl:value-of select="local-name(../..)"/>
</grandparent>
</xsl:for-each>
</nodeset-from-indoc>
我将获取每个节点的父母和祖父母的姓名:
<nodeset-from-indoc>
<parent>level2</parent><grandparent>level1</grandparent>
<parent>level2</parent><grandparent>level1</grandparent>
<parent>level2</parent><grandparent>level1</grandparent>
</nodeset-from-indoc>
但是,如果我将节点硬编码为变量:
<!-- a result-tree fragment -->
<xsl:variable name="my-rtf">
<level2>
<level3>1</level3>
</level2>
<level2>
<level3>2</level3>
</level2>
<level2>
<level3>3</level3>
</level2>
</xsl:variable>
这是不一个节点集,而是一个结果树片段,因为它们没有从输入文档中选择。结果树片段的问题在于您无法在其上使用XPath。例如,我不能这样做:
<xsl:for-each select="$my-rtf/level3">
这是node-set()
函数的用武之地。它是XSLT 1.0的扩展,它来自某些扩展名称空间,具体取决于您的XSLT处理器。许多处理器选择在EXSLT定义的命名空间中实现它。
正如Dmitre指出的那样,node-set()函数返回临时树的魔术文档节点,允许您使用XPath。 然而,这会导致选择需要完成的微妙转变。由于魔术文档节点,我必须在我的选择中包含level2
:
<nodeset-from-rtf>
<xsl:for-each select="exsl:node-set($my-rtf)/level2/level3">
<parent>
<xsl:value-of select="local-name(..)"/>
</parent>
<grandparent>
<xsl:value-of select="local-name(../..)"/>
</grandparent>
</xsl:for-each>
</nodeset-from-rtf>
在这种情况下,level3
节点将有父母,但没有祖父母:
<nodeset-from-rtf>
<parent>level2</parent><grandparent/>
<parent>level2</parent><grandparent/>
<parent>level2</parent><grandparent/>
</nodeset-from-rtf>
答案 2 :(得分:2)
节点集是一组节点。节点集中的每个节点都有祖先。节点集本身没有。如果$ NS是一个节点集,你可以$NS/ancestor::node()
:这将为你提供节点集中所有节点的所有祖先,并删除重复项。