如何在 Nokogiri 中使用 SAX 遍历内部节点



我对Nokogiri和Ruby很陌生,正在寻求一点帮助。

我正在使用class MyDoc < Nokogiri::XML::SAX::Document解析一个非常大的XML文件。现在我想遍历块的内部。

这是我的XML文件的格式:

<Content id="83087">
    <Title></Title>
    <PublisherEntity id="1067">eBooksLib</PublisherEntity>
    <Publisher>eBooksLib</Publisher>
    ......
</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

纯粹主义者可能不同意我的观点,但我一直这样做的方法是使用 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 比较棘手。我认为解决方案需要看起来像这样:

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

相关内容

  • 没有找到相关文章

最新更新