使用XPath查找特定命名空间中的所有属性

时间:2014-04-13 16:48:36

标签: ruby xml xpath nokogiri

我想知道我的XML文档中是否存在特定命名空间中的任何属性。我认为//@ns:*会这样做,但是这会找到所有名称空间的属性:

require 'nokogiri' # Ruby library using libxml2
doc = Nokogiri.XML '<r xmlns:f="f" xmlns:b="b"><e a="no" f:a="yes" b:a="no"/></r>'
p doc.xpath('//@f:*')
#=> [
#=>   #<Nokogiri::XML::Attr:0x3fca52c02888 name="a" value="no">,
#=>   #<Nokogiri::XML::Attr:0x3fca52c02874 name="a" namespace=#<Nokogiri::XML::Namespace:0x3fca52c02450 prefix="f" href="foo"> value="yes">,
#=>   #<Nokogiri::XML::Attr:0x3fca52c02860 name="a" namespace=#<Nokogiri::XML::Namespace:0x3fca52c08008 prefix="b" href="bar"> value="no">
#=> ]

当只查找与命名空间匹配的元素时,这种方法也适用:

doc = Nokogiri.XML '<r xmlns:f="foo" xmlns:b="bar"><e/><f:e/><b:e/></r>'
p doc.xpath('//f:*')
#=> [
#=>   #<Nokogiri::XML::Element:0x3fca524755ac name="e" namespace=#<Nokogiri::XML::Namespace:0x3fca5247555c prefix="f" href="foo">>
#=> ]

FWIW,Ruby中的非XPath解决方法是:

p doc.xpath('//@*').select{ |a| a.namespace && a.namespace.prefix=='f' }
#=> [
#=>   #<Nokogiri::XML::Attr:0x3fca52c02874 name="a" namespace=#<Nokogiri::XML::Namespace:0x3fca52c02450 prefix="f" href="foo"> value="yes">,
#=> ]

1 个答案:

答案 0 :(得分:1)

我希望有一个更优雅的答案,但这有效:

doc.xpath('//@*[namespace-uri()="uri-for-the-namespace-not-the-prefix"]')
#=> [
#=>   #<Nokogiri::XML::Attr:0x3fca5215e418 name="a" namespace=#<Nokogiri::XML::Namespace:0x3fca5215dff4 prefix="f" href="foo"> value="yes">
#=> ]