提问人:seane 提问时间:4/11/2014 最后编辑:Communityseane 更新时间:6/12/2015 访问量:521
Ruby Nokogiri SAX 解析器在 “>” 处截断字符串(又名“>”)
Ruby Nokogiri SAX parser truncates strings at ">" (aka ">")
问:
背景:我正在使用 Ruby 的 Nokogiri gem 来解析 XML 文件。我遇到的问题是,当字符串包含 时,SAX 解析器会返回不完整的结果,这是 的 HTML 编码。例如:>
>
<element>PART1PART2</element> #=> returns "PART1PART2"
<element>PART3>PART4</element> #=> returns "PART3"
我的解析器如下所示:
require 'nokogiri'
class MySample < Nokogiri::XML::SAX::Document
def characters(string)
puts string
end
end
# Create a new parser
parser = Nokogiri::XML::SAX::Parser.new(MySample.new)
# Feed the parser some XML
parser.parse_file(ARGV[0])
研究:如果一个字符串包含 ,那么 Nokogiri 认为这是字符串的结尾。在字符串中包含 a 将被视为格式不佳的 XML。但是,我的 XML 格式正确,但 Nokogiri 认为这标志着字符串的末尾。这意味着 Nokogiri 在解析字符串之前会解释 HTML(转换为 )。>
>
>
>
>
问题:为什么 Nokogiri 要解释 的 HTML,我怎样才能确保它解析完整的字符串?>
1 年更新 (FWIW)
自从我第一次发布这个问题以来已经一年多了,在这个时间点上,我还没有找到我最初问题的明确答案。因此,我想我会为将来遇到这篇文章的任何人提供一些更新。请记住,严格来说,我是 SAX 解析,而不是 DOM 解析。
要点:
最初的问题与 Nokogiri v1.6.1 有关。最新版本(在撰写本文时)是 v1.6.6,但问题仍未解决。
然而,这个问题有一个解决方法(参见下面的 matt 评论),但如果不是所有字符串的格式都相同(例如,一个字符串包含一次,另一个字符串包含两次,等等),则实现起来会很棘手。
>
>
我简要测试了另一个名为 Ox 的 Ruby 解析器,发现它没有与 Nokogiri 相同的问题。事实上,它可以正确处理包含 .此外,它还可以处理包含 .作为奖励,它的性能似乎比 Nokogiri 快(但它并非没有缺点)。
>
>
底线:
如果您在使用 Nokogiri 时遇到类似的问题,那么我建议您查看 Ox 作为可能的替代方案。我不会争辩说一种宝石比另一种更好(这不是目的)。但是,我可以保证 Ox 能够处理包含和/或 .>
>
答:
你没有说你为什么要尝试使用 SAX 解析器。Nokogiri 在使用 DOM 解析器解析文档时会正确处理文档:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<root>
<element>PART1PART2</element>
<element>PART3>PART4</element>
</root>
EOT
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <root>
# >> <element>PART1PART2</element>
# >> <element>PART3>PART4</element>
# >> </root>
您可能需要与开发人员的邮件列表进行核实。
评论
characters
方法“可能会在给定一个连续的字符串的情况下多次调用”,在这种情况下(至少对我而言),它被调用了三次——一次是 ,一次用于实体(传入),一次是 ,所以看起来 Nokogiri(或 libxml)正在围绕实体拆分字符串。你只看第一次调用时传递的内容吗?您需要缓冲多个调用以形成完整的字符串。PART3
>
PART4
characters
>
>
<
>