【问题标题】:How to get Nokogiri to parse XML with CDATA in &lt; and &gt;如何让 Nokogiri 在 < 和 > 中使用 CDATA 解析 XML
【发布时间】:2020-01-16 12:36:24
【问题描述】:

我有一个包含以下内容的 XML 文件:

<DATA>
    <NAME>&lt;![CDATA[FIRSTNAME LASTNAME MIDDLENAME ]]&gt;</NAME>
    <NUM>3731</NUM>
    <person_type>4</person_type>
    <birth_date>&lt;![CDATA[01.11.1992]]&gt;</birth_date>
    <DESCRIPTION>&lt;![CDATA[DESCRIPTION]]&gt;</DESCRIPTION>
</DATA>

我尝试用 Nokogiri 解析它,但没有 CDATA 我无法获取内容。

我的解析器脚本:

require 'nokogiri'

doc = Nokogiri::XML(File.open("test2.xml"))
root = doc.root

puts root['DATE']

doc.xpath('//DATA').each do |terr|
  puts "\nName: "+terr.xpath('NAME').text
end

这是我得到的:

Name: <![CDATA[FIRSTNAME LASTNAME MIDDLENAME ]]>

如何去掉结果中的“![CDATA[”?

我认为这完全是关于实体 &amp;lt;&amp;gt; 而不是 &lt;&gt;,但我无法让 Nokogiri 对它们做任何事情。

【问题讨论】:

  • 通常这是一个 XY 问题,因为 XML(或 HTML)已从其他地方错误地抓取并添加了实体。如果发生这种情况,正确的解决方案是找到原件并使用它。如果你不能,你可能必须预处理文件并强制实体解码 IF 它将导致语法正确的标记。如果不是,您可能必须提取它,然后让 Nokogiri 仅解析您需要的部分。我已经编写了数百个爬虫,并且不得不编写一些非常讨厌的代码来修复被多次破坏的标记。

标签: ruby-on-rails nokogiri


【解决方案1】:

您的输入包含转义的 &amp;lt;&amp;gt; 字符(&amp;lt;&amp;gt;)。当您使用字符而不是 HTML 实体时,一切都会按预期进行:

input = "<DATA>
    <NAME><![CDATA[FIRSTNAME LASTNAME MIDDLENAME ]]></NAME>
    <NUM>3731</NUM>
    <person_type>4</person_type>
    <birth_date><![CDATA[01.11.1992]]></birth_date>
    <DESCRIPTION><![CDATA[DESCRIPTION]]></DESCRIPTION>
</DATA>"
doc = Nokogiri::XML(input)
doc.xpath('//DATA/NAME').text

=> "FIRSTNAME LASTNAME MIDDLENAME "

doc.xpath('//DATA').each do |terr|
  puts "\nName: "+terr.xpath('NAME').text
end

=> Name: FIRSTNAME LASTNAME MIDDLENAME

要摆脱 HTML 实体,您可以在输入上调用 CGI.unescapeHTML

doc = Nokogiri::XML(CGI.unescapeHTML(File.read("test2.xml")))

【讨论】:

  • 感谢您的回复!这会导致 `unescapeHTML' 中的错误:没有将 File 隐式转换为 String (TypeError)
  • @PumPurum 请检查更新后的答案。而不是File.open 使用File.read
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
  • 1970-01-01
  • 2014-07-05
  • 2013-03-21
相关资源
最近更新 更多