Правильный способ анализа строки в XML DOM — это Nokogiri::XML
, Nokogiri.XML
или Nokogiri::XML.parse
, но не использование xml
.
Кроме того, теги XML не могут содержать ?
. Дополнительную информацию см. в спецификации. Вам придется покопаться в разделе «Имена и токены» и расшифровать описания шестнадцатеричных символов, чтобы выяснить допустимые диапазоны символов, но подсказка заключается в том, что ?
— это код символа 0x3f
.
Что приводит к тому, что XML в r
недействителен:
<?xml version="1.0" encoding="UTF-8"?>
<hash type="array">
<item><spec? type="boolean">false</spec?>
</item>
<hash>
Что при анализе приводит к:
irb(main):012:0> doc = Nokogiri::XML(r)
#<Nokogiri::XML::Document:0x80c8014c name="document" children=[#<Nokogiri::XML::Element:0x80c7399c name="hash" attributes=[#<Nokogiri::XML::Attr:0x80c733e8 name="type" value="array">] children=[#<Nokogiri::XML::Text:0x80c6e26c "\n ">, #<Nokogiri::XML::Element:0x80c6df60 name="item" children=[#<Nokogiri::XML::Element:0x80c6d970 name="spec">, #<Nokogiri::XML::Text:0x80c6d09c "? type=\"boolean\">false">]>, #<Nokogiri::XML::Text:0x80c6ca34 "?>\n ">]>]>
irb(main):013:0> doc.errors
[
[0] #<Nokogiri::XML::SyntaxError: error parsing attribute name>,
[1] #<Nokogiri::XML::SyntaxError: attributes construct error>,
[2] #<Nokogiri::XML::SyntaxError: Couldn't find end of Start Tag spec line 3>,
[3] #<Nokogiri::XML::SyntaxError: expected '>'>,
[4] #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: item line 3 and spec>,
[5] #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: hash line 2 and item>,
[6] #<Nokogiri::XML::SyntaxError: Extra content at the end of the document>
]
В результате Нокогири приходится исправлять DOM, чтобы попытаться разобраться в этом. Результирующий XML выглядит так:
irb(main):014:0> puts doc.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<hash type="array">
<item><spec/>? type="boolean">false</item>?>
</hash>
Чтобы это исправить, нужно передать Nokogiri действительный XML. Либо исправьте источник XML, если вы его контролируете, либо исправьте ошибки в строке, прежде чем передавать ее в Nokogiri.
По своему определению XML является строгим форматом, и Nokogiri соблюдает это и, стараясь быть дружелюбным, позволяет вам проверить errors
, чтобы убедиться, что это empty?
. Если это не так, велики шансы, что вам не следует продолжать использовать источник, пока вы не определите проблемы и не исправите все, что вызывает проблемы синтаксического анализа. Иногда проблема довольно безобидна, и вы можете игнорировать ее, но в любом случае вы должны, по крайней мере, осознавать ее.
Предварительно массировать данные до того, как Нокогири их увидит, несложно:
doc = Nokogiri::XML(r.gsub('spec?', 'spec'))
irb(main):024:0> puts doc.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<hash type="array">
<item><spec type="boolean">false</spec>
</item>
<hash>
</hash></hash>
nil
irb(main):025:0> doc.errors
[
[0] #<Nokogiri::XML::SyntaxError: Premature end of data in tag hash line 5>,
[1] #<Nokogiri::XML::SyntaxError: Premature end of data in tag hash line 2>
]
Это начало, но не попытка исправить это за вас полностью. Я учу тебя ловить рыбу, а не раздаю рыбу.
person
the Tin Man
schedule
20.03.2013