如何在XPath中通过属性命名空间查找元素

22

我想使用XPath查找所有具有给定命名空间中元素的元素。

例如,在以下文档中,我想查找foo:bardoodah元素:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

我知道可以使用以下XPath表达式从给定的命名空间中加载所有属性:

"//@*[namespace-uri()='http://foo.example.com']"

然而:

  • 这并没有给我元素,只是属性。
  • 当元素包含多个来自该命名空间的属性时,此选择器会按属性而不是按元素返回结果。

我是否能够得到我想要的内容,或者我必须收集属性并计算它们对应的唯一元素集合?


你是否忘记为 doodah 添加命名空间?因为我看不出它可以通过命名空间被选择。 - Emmanuel Rodriguez
如果解释不清楚,那是因为我在原始示例中使用了错误的命名空间。这是我的错误。 - Gareth
1
感谢您的帖子,它确实有所帮助。总结一下:
  • 获取具有给定命名空间属性的元素:
    //*[@*[namespace-uri()='http://foo.example.com']]
  • 获取给定命名空间的属性:
    //@*[namespace-uri()='http://foo.example.com']
- Lance
4个回答

28

使用:

//*[namespace-uri()='yourNamespaceURI-here'
   or
    @*[namespace-uri()='yourNamespaceURI-here']
   ]

使用XPath的or运算符,将两个条件组合成一个条件。

因此,该XPath表达式选择任何满足以下条件之一的元素:

  • 属于指定命名空间。
  • 具有属于指定命名空间的属性。

我只需要第二部分的内容 :) 我不知道你可以在谓词中嵌套谓词。已经相应地更新了我的帖子。 - Gareth
@Dimitre Novatchev,您能否看一下这里,这是命名空间的问题吗?谢谢。http://stackoverflow.com/questions/7007767/iphone-sdk-xml-mystery-after-adding-child-nodeforxpath-returns-nothing - Spring

4

我不确定你的意思是否是这样,但是只需在 XPath 中删除一个字符,即可获取特定命名空间中的所有元素:

//*[namespace-uri()='http://foo.example.com']

该命令的意思是“在该命名空间中找不到匹配的属性”。 - Johannes Weiss

1

你可以尝试一下

//*[namespace-uri()='http://foo.example.com' or @*[namespace-uri()='http://foo.example.com']]

如果你在 XML 数据中将 tal:quux 改为 foo:quux,它会给你元素 foo:bar 和元素 doodah:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com" xmlns:tal="xxx">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

这是你想要的吗?


不完全是这样... namespace-uri(./@*)='http://foo.example.com'] 只有当第一个属性(这取决于实现!)属于该命名空间时才返回 true。原始帖子希望选择元素,如果它的 任何 属性属于该命名空间。 - Dimitre Novatchev

0

你的XPath表达式几乎完美。不要请求属性"@",而是请求元素"",这样应该就可以了:

"//*[namespace-uri()='http://foo.example.com']"

你没有理解问题。OP希望选择任何属于命名空间或至少具有一个属于命名空间的属性的元素。你的表达式没有选择具有命名空间属性但元素不属于命名空间的元素。 - Dimitre Novatchev
谢谢您的澄清。我知道我没有理解问题,因为我在问题下面添加了一个评论,问为什么应该选择“doodah”。 - Emmanuel Rodriguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接