2015-03-30 72 views
2

我觉得,这是一个基本的XSLT问题。根据我的理解,节点集本身就是数据结构。从节点集()我无法导航到集外的任何节点。即我无法到达父母,也就是xml的开始或其兄弟姐妹。这是正确的吗?节点集()是否有一个祖先节点?

有没有办法得到一个节点集()

代码

<neighbourhood> 
<parent name = "xyz"> 
<child address=10> a </child> 
<child address=10> b </child> 
<child address=15> c </child> 
</parent> 
</neighbourhood> 

我有一组子节点的父。我需要消除重复“地址”的节点。 可以有n个“父”和m个“小孩”,并且可以有一个“孩子”的祖父节点。

最好的和合乎逻辑的方式可能是由每个家长去处理他们的孩子。但是,这是一个现有的代码库,这是一个简单的例子。我不想通过触摸调用者函数和其他模板来打破太多的事情。

所以,我的问题是,如果我可以用一组“孩子”获得“父”节点我有

感谢您的答复

+1

快速问题 - 为什么你需要?我从来不需要这样做,我想知道是否有更好的方法来做你正在做的事情。 – Flynn1179 2015-03-31 08:57:15

+0

是的!我也这么认为。我只是不确定什么是正确的方法可能。我已经用更多的细节更新了这个问题。我找到了一种解决方法来解决我的问题,但这可能不是最好的方法。 – user3208131 2015-03-31 15:37:11

+0

恐怕你的问题不再那么清楚了。如果您的目标是消除重复,那么 - 假设这是关于XSLT 1.0的 - 为此使用[Muenchian分组](http://www.jenitennison.com/xslt/grouping/muenchian.html),或者 - 如果您的处理器支持它 - EXSLT'set:distinct()'函数。无论如何,在这种背景下什么是“节点集”并不清楚,这样的集合的祖先将在这方面扮演什么角色。 – 2015-03-31 15:59:08

回答

3

是否节点集()有祖先节点?

node-set()是(扩展)功能 - 不是节点。一个函数不能拥有祖先,因为它不是一个节点。

我想通过"node-set()"在问题中,您的意思是由xxx:node-set()函数返回的值(其中前缀“xxx”绑定到供应商特定的命名空间)。如果是这样,在这里是有用的答案:

根据定义,xxx:node-set()函数返回document-node()(也称为root-node XPath 1.0中)的临时树,这是通过转换RTF获得的(结果树片段) ,作为这个函数的唯一参数传递。

按照定义,文档节点位于文档层次结构的顶部,并且是XML文档中没有父节点的唯一节点。

因此,被调用xxx:node-set()函数返回的节点没有任何祖先

从节点集()我无法导航到集外的任何节点。即我无法到达父母,也就是xml的开始或其兄弟姐妹。这是正确的吗?

是的,而不调用从另一文档返回一个节点(诸如标准XPath函数id()或标准XSLT功能document()),或引用变量/参数的另一个功能,是不可能导航到一个仅通过使用XPath位置步骤从另一个文档创建节点。

有没有办法得到一个节点集()

号,由xxx:node-set()函数返回的节点是文档节点和文档节点没有按的父没有父母(或任何其他祖先)节点。

+0

感谢您确认此 – user3208131 2015-03-31 15:30:04

+0

@ user3208131,不客气。 – 2015-03-31 15:49:27

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> 

这是不节点集,但结果树片断,由于y没有从输入文件中选择。结果树片段的问题是你不能在它们上使用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> 
+0

我应该更具体。我正在讨论Dimitre猜测的node-set()函数,它可以在RTF节点上工作。但是,感谢您的解释 – user3208131 2015-03-31 15:29:32

2

节点集是一组节点。节点集中的每个节点都有祖先。节点集本身不。如果$ NS是节点集,则可以执行$NS/ancestor::node():这将为您提供节点集中所有节点的所有祖先,并消除重复项。

+0

“节点集本身不”谢谢,迈克尔,以确认这一点。 – user3208131 2015-03-31 15:27:16

相关问题