ruby-on-rails - (Rails) 无法让 Mechanize 正确读取 web xml 文件

标签 ruby-on-rails xml ruby-on-rails-3 parsing mechanize

我必须读取可通过身份验证通过 http 访问的 xml 文件。这就是我使用 Mechanize 的原因。

我的问题是我无法 Mechanize 来识别这些 XML 文件,因此我可以对它们使用 .find 或 .search。

这是我首先尝试的 - 在我看来(html 文件)
<% agent = Mechanize.new %><% page = agent.get("http://dl.dropbox.com/u/344349/xml.xml") %><%= page %>
返回 #<Mechanize::File:0x007f9dd602de30> .它是 ::File而不是 ::Page我不能对此使用 .find 或 .search,因为它会出错 undefined method find for #<Mechanize::File:0x007f9dd624cbd0>
Mechanize 文档说:这是 Pluggable Parsers 的默认(和基)类。如果 Mechanize 找不到用于内容类型的合适类,则将使用此类。例如,如果您下载一个 JPG,Mechanize 将不知道如何解析它,因此该类将被实例化。

所以我创建了一个类,如下所述:http://rdoc.info/github/tenderlove/mechanize/master/Mechanize/PluggableParser
My classclass XMLParser < Mechanize::Fileattr_reader :xmldef initialize(uri=nil, response=nil, body=nil, code=nil)super(uri, response, body, code)@xml = xml.parse(body)endend
以及我 View 中的更新代码(html 文件)
<% agent = Mechanize.new %><% agent.pluggable_parser['text/xml'] = XMLParser %><% agent.user_agent_alias = 'Windows Mozilla' %><% page = agent.get("http://dl.dropbox.com/u/344349/xml.xml") %><%= page %>
甚至
<% agent = Mechanize.new %><% agent.pluggable_parser.xml = XMLParser %><% page1 = agent.get('http://dl.dropbox.com/u/344349/xml.xml') # => CSVParser %><%= page1 %>
仍然返回 #<Mechanize::File:0x007f9dd5253b48>
我什至测试了确切的代码(CSVParser - http://rdoc.info/github/tenderlove/mechanize/master/Mechanize/PluggableParser)并尝试加载一个仍然被视为::File 的 csv 文件。

我究竟做错了什么 ?

最佳答案

好的,所以我刚刚为自己解决了这个问题。解决方案分为两部分:

首先,您匹配的内容类型不正确。如果你运行这一行,在你执行 get 之后,它会告诉你你得到的文档的内容类型是什么:

page.response['content-type'] # => 'application/xml', not 'text/xml'

当我使用 mechanize 获取您的页面 ('http://dl.dropbox.com/u/344349/xml.xml') 时,我将 'application/xml' 视为内容类型。

其次,您没有正确使用 PluggableParser。在这里使用 XMLParser 将生成 NoMethodError: undefined method 'parse' for nil:NilClass .更改类定义以使用 Nokogiri::XML 代替:
class XmlParser < Mechanize::File
  attr_reader :xml
  def initialize(uri = nil, response = nil, body = nil, code = nil)
    @xml = Nokogiri::XML(body)
    super uri, response, body, code
  end
end

然后,将其设置为正确内容类型的解析器:
mech.pluggable_parser['application/xml'] = XmlParser

要使用它,您将获得与以前相同的页面,然后将页面对象的 xml 属性引用为 Nokogiri::XML::Document实例,它是 Nokogiri::XML::Node 的子类.幸运的是,Mechanize::Page.search只是 Nokogiri::XML::Node.search 的包装器,因此您几乎可以按照您期望的方式进行搜索。像这样:
page.xml.search 'catalog'

进一步的改进是将 XmlParser.search 映射到 Nokogiri .search 方法:
# This is the same as what Mechanize::Page does
class XmlParser < Mechanize::File
  extend Forwardable
  def_delegators  :@xml, :search, :/, :at
end

这使您可以直接在页面实例上执行搜索:
page.search 'catalog'

关于ruby-on-rails - (Rails) 无法让 Mechanize 正确读取 web xml 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9342749/

相关文章:

ruby-on-rails - 追踪导致 rspec 测试缓慢的原因

ruby-on-rails - 如何编写一个 Rails 查找器方法来返回按记录分组的最大日期?

python - 如何从 openerp 中的帐户报告打印单一合作伙伴分类帐报告

javascript - 从 javascript 调用 XSLT

sql - 如何访问 Rails3 中的连接表属性?

ruby-on-rails - 在数组中发送数据的多个单选按钮组

iphone - 如何从视频中提取方向信息?

java - 将数字四舍五入到小数点后第一位

ruby-on-rails - 如果您在操作中重定向,过滤器链是否会中断?

ruby-on-rails - Rails 中运行时的动态路由