我正在尝试使用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
或者其他类似的