如果您使用的是 HTTPParty,并且它试图在您动手之前解析传入的 XML,那么您需要将该过程拆分为 get 和 parse,以便您可以在两者之间放置代码。
出于这些原因,我使用 OpenURI 和 Nokogiri,但是无论您使用这两个还是它们的等价物,您都将有机会在解析 XML 之前对其进行预处理。' &
' 在裸露时是非法字符;它应该被编码或在 CDATA 块中,但不幸的是,在互联网的狂野中,有很多格式错误的 XML 提要和文件。
我喜欢 Nokogiri 完成这项任务的一点是,它一直在不停地运转,至少在它可以做到的范围内。您可以查看文档解析后是否有错误,您可以调整其解析器设置以控制它将做什么或抱怨:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<a>
<b parm="4860 BOOMM 10x20 MD&">foobar</b>
</a>
EOT
puts doc.errors
puts doc.to_xml
这将输出:
xmlParseEntityRef: no name
<?xml version="1.0"?>
<a>
<b parm="4860 BOOMM 10x20 MD">foobar</b>
</a>
请注意,Nokogiri 剥离了,&
但我仍然能够获得可用的输出。您必须决定是否需要错误并停止使用该STRICT
选项,或者继续,但 Nokogiri 可以根据您的需要执行任何一项。
您可以按摩传入的 XML:
require 'nokogiri'
xml = <<EOT
<a>
<b parm="4860 BOOMM 10x20 MD&">foobar</b>
</a>
EOT
xml['MD&'] = 'MD&'
doc = Nokogiri::XML(xml) do |config|
config.strict
end
puts doc.errors
puts doc.to_xml
现在输出:
<?xml version="1.0"?>
<a>
<b parm="4860 BOOMM 10x20 MD&">foobar</b>
</a>
我知道这不是一个完美的答案,但根据我处理大量 RSS/Atom 和 XML/HTML 解析的经验,有时我们必须打开脏套路,选择任何可行的方法而不是优雅的方法。
HTTParty 中通向必杀技的另一条途径是对parser 进行子类化。您应该能够进入解析器的 XML 流并在那里对其进行按摩。从文档:
# Intercept the parsing for all formats
class SimpleParser < HTTParty::Parser
def parse
perform_parsing
end
end