如何为不同的父节点选择具有相同名称的所有节点?

时间:2011-10-20 08:57:35

标签: xml xslt xpath

假设我有以下xml:

<root>
  <person>
    <name>John</name>
  </person>
  <children>
    <person>
      <name>Jack</name>
    </person>
  </children>
</root>

是否可以同时选择这两个人?假设我不知道另一个人在儿童标签中,他们可能很容易在配偶标签或完全不同的东西,可能在另一个孩子。我知道我需要的所有人都在根标签中(不一定是文件根目录)。

5 个答案:

答案 0 :(得分:10)

您可以使用

//person

//*[local-name()='person']

在文档中查找任何person元素,但要小心 - 某些xsl处理器(如Microsoft),双斜杠的性能在大型xml文档上可能会很差,因为文档中的所有节点都是如此需要进行评估。

编辑:
如果您知道“人”只有两条路径,那么您可以完全避免使用//

<xsl:for-each select="/root/person | /root/children/person">
    <outputPerson>
        <xsl:value-of select="name/text()" />
    </outputPerson>
</xsl:for-each>

OR命名空间不可知:

<xsl:for-each select="/*[local-name()='root']/*[local-name()='person'] 
  | /*[local-name()='root']/*[local-name()='children']/*[local-name()='person']">

答案 1 :(得分:3)

在Petar Ivanov的回答中,//的定义是错误的

以下是 XPath 1.0 W3C Specification 的正确定义:

  

///descendant-or-self::node()/

的缩写

答案 2 :(得分:1)

//name

将匹配两者,无论它们在xml树中的哪个位置。

  

//从当前节点中选择与选择匹配的文档中的节点,无论它们在何处(link

答案 3 :(得分:1)

或者您可以使用:

根//人

所以你只在root元素中搜索persion

答案 4 :(得分:1)

正如nonnb所说,对于大型xml文档,双斜杠的性能很差。

所以//name可以做到这一点,但可能会带来更多你期望的元素。 另外,想象一下,在你的根元素中你有一些元素,这些元素可能不具有名为 name 的后代元素,根据你不想提出的问题,//name会把它们搞砸。

你应该在最大程度上关注你的context-node,这样你的XPath将是最佳的。

对于这个精确的文件,我会使用

/root/descendant::person/name

希望它有所帮助,