文字列をXMLDOMに解析する適切な方法はNokogiri::XML
、またはNokogiri.XML
またはNokogiri::XML.parse
ですが、を使用しませんxml
。
また、XMLタグにを含めることはできません?
。詳細については、仕様を参照してください。「名前とトークン」セクションを掘り下げ、16進文字の説明をデコードして、許可される文字の範囲を把握する必要がありますが、ヒント?
は文字コード0x3f
です。
r
これは、のXMLが無効であるという事実につながります。
<?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>
]
その結果、Nokogiriは、それを理解するために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はそれを尊重し、親しみやすくすることで、XMLかどうかを確認できるようにし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>
]
これは始まりですが、完全に修正する試みではありません。私はあなたに魚を配るのではなく、魚を教えることを教えています。