假设我有以下xml:
<root>
<person>
<name>John</name>
</person>
<children>
<person>
<name>Jack</name>
</person>
</children>
</root>
是否可以同时选择这两个人?假设我不知道另一个人在儿童标签中,他们可能很容易在配偶标签或完全不同的东西,可能在另一个孩子。我知道我需要的所有人都在根标签中(不一定是文件根目录)。
答案 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)
答案 3 :(得分:1)
或者您可以使用:
根//人
所以你只在root元素中搜索persion
答案 4 :(得分:1)
正如nonnb所说,对于大型xml文档,双斜杠的性能很差。
所以//name
可以做到这一点,但可能会带来更多你期望的元素。
另外,想象一下,在你的根元素中你有一些元素,这些元素可能不具有名为 name 的后代元素,根据你不想提出的问题,//name
会把它们搞砸。
你应该在最大程度上关注你的context-node,这样你的XPath将是最佳的。
对于这个精确的文件,我会使用
/root/descendant::person/name
希望它有所帮助,