1

我试图使用 HTTParty gem 下载一个包含“&”符号的 xml 文件,但出现此错误:

"treeparser.rb:95:in `rescue in parse' <RuntimeError: Illegal character '&' 
 in raw string  "4860 BOOMM 10x20 MD&"> (MultiXml::ParseError)"

这是我的代码:

class SAPOrders
  include HTTParty
  default_params :output => 'xml'
  format :xml
  base_uri '<webservice url>'
end

xml =  SAPOrders.get('/<nameOfFile.xml>').inspect

我错过了什么?

4

1 回答 1

3

如果您使用的是 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&amp;'

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&amp;">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
于 2012-01-26T23:31:55.400 回答