Как запросить элементы, содержащие attributeNameA с namespaceB с "css"? - PullRequest
0 голосов
/ 05 января 2012

Моя проблема отличается от " Как я могу получить значения атрибутов в пространстве имен, используя Nokogiri? ".

мой XML содержит атрибуты с пространствами имен. Как запросить элементы, содержащие attributeNameA с namespaceB (namespaceB:attributeNameA="attributeAValue"), используя метод css Нокогири?

Это мой код:

xmlContent = %Q|
<?xml version="1.0"?>
<ns1:el1 xmlns:ns1="blabla" >
    <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
    <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
</ns1:el1>|
xml_doc  = Nokogiri::XML(xmlContent)

#no namespace
result = xml_doc.css('ns1|el2[att]')
result.each {|i| puts i}

#with namespace
result = xml_doc.css('ns1|el2[ns1|att]') #error unexpexted '|'
result.each {|i| puts i}

Отредактировано 6 января 2011 г .: По этой ссылке: https://github.com/tenderlove/nokogiri/issues/257#issuecomment-3365636 Nokogiri не поддерживает непосредственный запрос элементов xml с атрибутом namespace.

Реальный вариант использования - изменение пакета служб SSIS (* .dtsx); Я не могу запросить все элементы с атрибутом DTS: имя, содержащее "projectVar _".

Я должен сообщить команде nokogiri об этом случае использования.

1 Ответ

1 голос
/ 05 января 2012

Когда вы анализируете ваш документ, Нокогири пытается понять его и не понимает декларацию пространства имен:

puts xml_doc.errors

возвращается:

[#<Nokogiri::XML::SyntaxError: XML declaration allowed only at the start of the document>]

Это из-за XML DECL:

<?xml version="1.0"?>

Удаление, которое устраняет эту проблему.

То, как вы обращаетесь к атрибутам узлов, тоже неверно:

result = xml_doc.css('ns1|el2[att]')
result.each {|i| puts i}

должно быть:

result = xml_doc.css('ns1|el2')
result.each { |i| puts i['att'] }

Попытка получить доступ к атрибуту пространства имен с пространством имен является странной. Я не помню, чтобы когда-либо видел атрибут пространства имен. Нокогири это тоже не нравится:

Если я запускаю это:

require 'nokogiri'

xmlContent = %Q|
<ns1:el1 xmlns:ns1="blabla">
  <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
  <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
</ns1:el1>|

xml_doc = Nokogiri::XML(xmlContent)
puts xml_doc.errors 

puts "Searching for: 'att' attribute"
result = xml_doc.css('ns1|el2')
result.each { |i| puts i['att'] }

puts "Searching for: 'ns1|att' attribute"
result = xml_doc.css('ns1|el2')
result.each { |i| puts i['ns1|att'] }

Я получаю это:

Searching for: 'att' attribute
123
noNameSpace
Searching for: 'ns1|att' attribute

result.first # => #<Nokogiri::XML::Element:0x8051e19c name="el2" namespace=#<Nokogiri::XML::Namespace:0x8051f344 prefix="ns1" href="blabla"> attributes=[#<Nokogiri::XML::Attr:0x8051e084 name="att" namespace=#<Nokogiri::XML::Namespace:0x8051f344 prefix="ns1" href="blabla"> value="123">] children=[#<Nokogiri::XML::Text:0x80519e30 "with namespace">]>
result.first.keys # => ["att"]
result.first.values # => ["123"]
result.first['att'] # => "123"
result.first['ns1|att'] # => nil
result.first['ns1:att'] # => nil

result.last # => #<Nokogiri::XML::Element:0x8051356c name="el2" namespace=#<Nokogiri::XML::Namespace:0x8051f344 prefix="ns1" href="blabla"> attributes=[#<Nokogiri::XML::Attr:0x805133a0 name="att" value="noNameSpace">] children=[#<Nokogiri::XML::Text:0x805122d4 "no namespace">]>
result.last.keys # => ["att"]
result.last.values # => ["noNameSpace"]
result.last['att'] # => "noNameSpace"
result.last['ns1|att'] # => nil
result.last['ns1:att'] # => nil
...