将字符串解析为 XML DOM 的正确方法是Nokogiri::XML
orNokogiri.XML
或Nokogiri::XML.parse
,但不使用xml
.
此外,XML 标记不能包含?
. 有关更多信息,请参阅规范。您必须深入研究“名称和令牌”部分并解码十六进制字符描述以找出允许的字符范围,但提示?
是字符代码0x3f
。
这导致 XML inr
无效的事实:
<?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 尊重这一点,并且为了友好,您可以检查errors
它是否empty?
. 如果不是,那么在确定问题并修复导致解析问题的任何原因之前,您不应该继续使用源代码。有时问题是相当良性的,您可以忽略它,但无论哪种情况,您至少应该意识到它。
在 Nokogiri 发现之前预先按摩数据并不难:
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>
]
这是一个开始,但不是试图为您完全修复它。我教你钓鱼,而不是分发鱼。