0

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

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

这是我的 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
4

2 回答 2

2

纯粹主义者可能不同意我的观点,但我一直这样做的方式是使用 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),但就我而言,它可以轻松完成工作。

于 2013-11-13T00:24:22.237 回答
0

使用 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
于 2012-06-04T08:13:23.103 回答