【问题标题】:Ruby Nokogiri SAX parser truncates strings at ">" (aka ">")Ruby Nokogiri SAX 解析器在“>”(又名“>”)处截断字符串
【发布时间】:2014-05-24 15:32:59
【问题描述】:

背景:我正在使用 Ruby 的 Nokogiri gem 来解析 XML 文件。我遇到的问题是,当字符串包含>> 的 HTML 编码)时,SAX 解析器返回不完整的结果。例如:

<element>PART1PART2</element> #=> returns "PART1PART2"
<element>PART3&gt;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])

研究:如果一个字符串包含&amp;gt;,那么Nokogiri 认为这是字符串的结尾。在字符串中包含&amp;gt; 将被视为格式不正确的 XML。但是,我的 XML 格式正确,但 Nokogiri 认为 &amp;gt; 标记了字符串的结尾。这意味着 Nokogiri 在解析字符串之前正在解释 HTML(将 &amp;gt; 转换为 &amp;gt;)。

问题:为什么 Nokogiri 为&amp;gt; 解释 HTML,我如何确保它解析完整的字符串?


1 年更新 (FWIW)

自从我第一次发布这个问题以来已经一年多了,此时我还没有对我最初的问题找到明确的答案。因此,我想我会为将来遇到这篇文章的任何人提供一些更新。请记住,我说的是 SAX 解析,而不是 DOM 解析。

要点:

  • 最初的问题是关于 Nokogiri v1.6.1。最新版本(在撰写本文时)是 v1.6.6,但问题仍未解决。

  • 1234563 ,另一个字符串包含两次&amp;gt;,等等)。
  • 我简单地测试了另一个名为 Ox 的 Ruby 解析器,发现它没有与 Nokogiri 相同的问题。事实上,它正确处理包含&amp;gt; 的字符串。此外,它还可以处理包含&amp;gt; 的字符串。作为奖励,it appears to perform faster than Nokogiri (but it's not without its faults)

底线:

如果您对 Nokogiri 也有类似的问题,那么我建议您查看 Ox 作为可能的替代方案。我不会争辩说一颗宝石比另一颗更好(这不是它的用途)。不过,我可以保证 Ox 能够处理包含 &amp;gt; 和/或 &amp;gt; 的字符串。

【问题讨论】:

  • +1 以很好的方式提出问题..
  • 这对我来说没问题。请注意characters method “might be called multiple times given one contiguous string of characters”,在这种情况下(至少对我而言)它被调用 三次 次——一次使用PART3,一次用于实体(传入&amp;gt;),一次使用PART4,所以看起来 Nokogiri(或 libxml)正在围绕实体拆分字符串。您是否只查看第一次调用时传递的内容?您需要缓冲对characters 的多次调用以形成完整的字符串。
  • 你是绝对正确的。这是我最终实施的解决方法,但并不理想。当每个字符串都具有相同数量的&amp;gt; 时,它工作正常,但我的字符串没有。我让它工作了,但它非常难看,所以我希望关闭 HTML 解释以使事情更清洁。
  • 另外:&amp;gt; 在这里实际上是有效的(&lt; 不会,但&amp;gt; 可以)。
  • 你是对的。但是,W3Schools 说,“大于字符是合法的,但替换它是一个好习惯。”我已经采取了这种预防措施,所以(除非我完全错过了什么)我有点失望 Nokogiri 没有相应地处理它。

标签: ruby xml xml-parsing nokogiri sax


【解决方案1】:

您没有说明为什么要尝试使用 SAX 解析器。 Nokogiri 在使用 DOM 解析器解析文档时正确处理文档:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<root>
  <element>PART1PART2</element>
  <element>PART3&gt;PART4</element>
</root>
EOT

puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <root>
# >>   <element>PART1PART2</element>
# >>   <element>PART3&gt;PART4</element>
# >> </root>

您可能想与their mail-list 上的开发人员联系。

【讨论】:

  • 好点。我忘了提到我正在解析的 XML 文件太大,无法使用 DOM 解析器加载到内存中。
猜你喜欢
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多