我有一个大型的本地XML文件(24 GB),其结构如下:
<id>****</id>
<url> ****</url> (several times within an id...)
我需要这样的结果:
id1;url1
id1;url2
id1;url3
id2;url4
....
我想将Nokigiri用于SAX Parser或Reader,因为我无法将整个文件加载到内存中。我正在使用Ruby Rake任务来执行代码。
我的SAX代码是:
task :fetch_saxxml => :environment do
require 'nokogiri'
require 'open-uri'
class MyDocument < Nokogiri::XML::SAX::Document
attr_accessor :is_name
def initialize
@is_name = false
end
def start_element name, attributes = []
@is_name = name.eql?("id")
end
def characters string
string.strip!
if @is_name and !string.empty?
puts "ID: #{string}"
end
end
def end_document
puts "the document has ended"
end
end
parser = Nokogiri::XML::SAX::Parser.new(MyDocument.new)
parser.parse_file('/path_to_my_file.xml')
end
这样可以获取文件中的ID,但我也需要在每个id节点中获取URL。
如何在该代码中添加“each do”之类的内容来获取URL并获得如上所示的输出?或者是否可以在“字符”中调用多个动作?
答案 0 :(得分:0)
实际上,这是解析几个节点发生时的解决方案。 SAX解析器的问题是你必须找到一种方法来处理像“&amp;”这样的特殊字符。等等......但这是另一个故事。
这是我的代码:
class MyDoc < Nokogiri::XML::SAX::Document
def start_element name, attrs = []
@inside_content = true if name == 'yourvalue'
@current_element = name
end
def characters str
if @current_element == 'your_1st subnode'
elsif @current_element == 'your 2nd subnode'
end
puts "#{@current_element} - #{str}" if @inside_content && %w{your_subnodes here}.include?(@current_element)
end
def end_element name
@inside_content = false if name == 'yourvalue'
@current_element = nil
end
end
parser = Nokogiri::XML::SAX::Parser.new(MyDoc.new)
parser.parse_file('/path_to_your.xml')
end