Использование XPath для поиска всех атрибутов в определенном пространстве имен

Я хотел бы видеть, существуют ли какие-либо атрибуты в моем документе 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, обходной путь без XPath в Ruby:

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 ответ

Я надеюсь, что есть более элегантный ответ, но это работает:

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">
#=> ]
Другие вопросы по тегам