首页 > 解决方案 > 无法让 ruby​​ 使用 Nokogiri 解析我的 XML

问题描述

我是 Ruby 的新手,并且有一段时间尝试对我的 XML 进行简单的树遍历,看起来像这样:

<fx:Container>
    <fx:topic>Exchange rates</fx:topic>
    <fx:Provider>
        <fx:name>Standard Bank</fx:name>
    </fx:Provider>
    <Cube>
        <Cube time="2018-12-06">
            <Cube currency="USD" rate="1.1351"/>
            <Cube currency="JPY" rate="128.04"/>
            ... and more currencies
        </Cube>
        <Cube time="2018-12-05">
            <Cube currency="USD" rate="1.1301"/>
            <Cube currency="JPY" rate="129.36"/>
            ... and more currencies
        </Cube>
        ... and so on for more dates
    </Cube>
</fx:Container>

XML 没有 DTD,节点的命名不受我控制。

因此,如果您想象一个类 (ForEx) 具有日期、货币和汇率三个字段,那么我只想创建一个由日期和货币唯一键控的 ForEx 实例的 Ruby 集合(这样我就可以将它们放入 SQLite 表中)。

我得到一个'doc'变量就好了:

doc = Nokogiri::XML(open("http://www.blahblah/forex.xml"))

然后尝试了这个及其变体:

doc.xpath('//fx:Container//Cube')

但不断得到空集合。

我已经真正尝试过各种搜索,以查找以前已经完成的示例,但找不到任何对我有帮助的东西。

请提供任何帮助。

编辑:

require 'nokogiri'
require 'open-uri'

class DevDataFeed
  def self.xml_parser
    doc = Nokogiri::XML(open("http://www.blahblah/ForEx.xml"))
    puts "doc class: " + doc.class.to_s
    block = doc.xpath("//fx:Container/Cube")
    puts "block class: " + block.class.to_s
    puts block.count

  end
end

datafeed = DevDataFeed.new
DevDataFeed.xml_parser

输出:

doc class: Nokogiri::XML::Document
block class: Nokogiri::XML::NodeSet
0

标签: rubyxmlnokogiri

解决方案


您需要将命名空间信息传递给xpath,例如:

block = doc.xpath("//fx:Container/Cube", 'fx' => '???')

或使用:

block = doc.xpath("//*[local-name()='Container']/Cube")

或者完全删除命名空间:

doc.remove_namespaces!
block = doc.xpath("//fx:Container/Cube")

推荐阅读