如何使用Nokogiri::XML::Reader解析大型XML文件



我正在尝试使用Ruby的Nokogiri来解析大型(1gb或更多)XML文件。我在一个较小的文件上测试代码,这里只包含4条记录。我在Ubuntu 10.10上使用Nokogiri版本1.5.0,Ruby 1.8.7。因为我不太懂SAX,所以我试着从Nokogiri::XML::Reader开始。

我的第一次尝试,检索PMID标签的内容,看起来像这样:

#!/usr/bin/ruby
require "rubygems"
require "nokogiri"
file   = ARGV[0]
reader = Nokogiri::XML::Reader(File.open(file))
p      = []
reader.each do |node|
  if node.name == "PMID"
    p << node.inner_xml
  end
end
puts p.inspect

这是我希望看到的:

["21714156", "21693734", "21692271", "21692260"]

下面是我实际看到的:

["21714156", "", "21693734", "", "21692271", "", "21692260", ""]

似乎由于某种原因,我的代码正在为每个PMID实例查找或生成一个额外的空PMID标记。或者是inner_xml不像我想象的那样工作。

如果有人能确认我的代码和数据生成显示的结果,并建议我在哪里出错,我将不胜感激。

流中的每个元素都以两个事件的形式出现:一个用于打开元素,一个用于关闭元素。开幕活动将有

node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT

和结束事件将具有

node.node_type == Nokogiri::XML::Reader::TYPE_END_ELEMENT

您看到的空字符串只是元素关闭事件。请记住,使用SAX解析,您基本上是在遍历树,因此需要第二个事件来告诉您何时返回并关闭元素。

你可能想要更像这样的东西:

reader.each do |node|
  if node.name == "PMID" && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
    p << node.inner_xml
  end
end

或者:

reader.each do |node|
  next if node.name      != 'PMID'
  next if node.node_type != Nokogiri::XML::Reader::TYPE_ELEMENT
  p << node.inner_xml
end

或者其他类似的

相关内容

  • 没有找到相关文章

最新更新