Ruby 如何在Nokogiri中使用SAX遍历内部节点?
我对Nokogiri和Ruby还很陌生,正在寻求一些帮助 我正在使用Ruby 如何在Nokogiri中使用SAX遍历内部节点?,ruby,nokogiri,sax,Ruby,Nokogiri,Sax,我对Nokogiri和Ruby还很陌生,正在寻求一些帮助 我正在使用classmydoc
classmydoc
解析一个非常大的XML文件。现在我想遍历块的内部
以下是我的XML文件的格式:
<Content id="83087">
<Title></Title>
<PublisherEntity id="1067">eBooksLib</PublisherEntity>
<Publisher>eBooksLib</Publisher>
......
</Content>
电子书
电子书
......
我已经知道是否找到了“Content”标记,现在我想知道如何遍历它的内部。以下是我的简短代码:
class MyDoc < Nokogiri::XML::SAX::Document
#check the start element. set flag for each element
def start_element name, attrs = []
if(name == 'Content')
#get the <Title>
#get the <PublisherEntity>
#get the Publisher
end
end
def cdata_block(string)
characters(string)
end
def characters(str)
puts str
end
end
classmydoc
使用SAX更为棘手。我认为解决方案需要如下所示:
class MyDoc < Nokogiri::XML::SAX::Document
def start_element name, attrs = []
@inside_content = true if name == 'Content'
@current_element = name
end
def end_element name
@inside_content = false if name == 'Content'
@current_element = nil
end
def characters str
puts "#{@current_element} - #{str}" if @inside_content && %w{Title PublisherEntity Publisher}.include?(@current_element)
end
end
classmydoc
纯粹主义者可能不同意我的观点,但我的做法是使用Nokogiri遍历巨大的文件,然后使用XmlSimple处理文件中较小的对象。以下是我的代码片段:
require 'nokogiri'
require 'xmlsimple'
def isend(node)
return (node.node_type == Nokogiri::XML::Reader::TYPE_END_ELEMENT)
end
reader = Nokogiri::XML::Reader(File.open('database.xml', 'r'))
# traverse the file looking for tag "content"
reader.each do |node|
next if node.name != 'content' || isend(node)
# if we get here, then we found start of node 'content',
# so read it into an array and work with the array:
content = XmlSimple.xml_in(node.outer_xml())
title = content['title'][0]
# ...etc.
end
这对我很有效。有些人可能反对在同一代码中混合使用SAX和非SAX(nokogiri和XmlSimple),但出于我的目的,它以最小的麻烦完成了工作。为什么使用SAX?您很有可能正在寻找Nokogiri.XML。XML文件至少为1GIG,因此我希望它具有内存效率。+1是的,这实际上是使用SAX的一个很好的理由