使用Nokogiri SAX从节点中选择孩子?

时间:2014-06-17 08:15:41

标签: ruby xml xpath nokogiri sax

对于Nokogiri :: XML :: SAX :: Document有没有像(accessions = doc.at_xpath('//Node/Childtag').content)这样的类似方法?

我有XML:

<accession>Police-1234</accession>
<accession>Police-6574</accession>    
<police>
    <privateCar>
      <fullName>BMW 750Li</fullName>
    </privateCar>
    <officeCar>
        <fullName>Ford Mustang GT</fullName>
    </officeCar>
    <optional>
       <fullName>Porsche carrera 511</fullName>
    </optional>
    </police>

我的代码有点像:

require 'rubygems'
require 'nokogiri'

include Nokogiri

class PostCallbacks < XML::SAX::Document


  def initialize
     @in_title = false
   @in_title2 = false
    end

  def start_element(element, attributes)
  @attrs = attributes
  @content = ''
  @in_title = element.eql?("accession")
  # Collecting all the other nodes/tags
  @in_title2 = element.eql?("fullName")
  end



  def end_document
       # puts "Here is where the attributes could be played with"
  end


  def characters string

    string.strip!
    if @in_title and !string.empty?
          puts "Accession: #{string}"

    elsif @in_title2 and !string.empty?
          puts "Full Name: #{string}"
    end

    @content << string if @content

  end

end


parser = XML::SAX::Parser.new(PostCallbacks.new)
parser.parse(File.open(ARGV[0]))

我的结果是:

Accessions:Police-1234
Accessions:Police-6574

Full Name: BMW 750Li
Full Name: Ford Mustang GT
Full Name: Porsche carrera 511

现在我有两个问题。

  1. 我如何仅限制收集值为“Police-1234”的“accession”元素。
  2. 我想只检索privateCar的孩子的全名。即我只想要BMW 750Li作为我的结果。
  3. 首先,我通常使用doc.xpath(//accession).first来提取XML中的第一个条目。

    对于第二点,我知道我可以使用带有doc.at_xpath(//police/privateCar/fullName)的XPath来选择它,但SAX解析器有类似的东西吗?

    我正在使用SAX,因为我有一个要解析的大型XML文件。

1 个答案:

答案 0 :(得分:1)

简短的回答是否定的,SAX中没有类似的功能。

您并不了解SAX解析和DOM解析之间的区别。通常,当我们使用Nokogiri时,我们正在使用足够小的文档以适应内存并将其解析为DOM(&#34; document object model)。只要能够遍历文档并进行搜索,这就具有巨大的优势,因为我们可以根据需要经常从文档的顶部回放和搜索而不会受到惩罚。并且,因为它全部在内存中,所以我们很容易告诉解析器根据一串节点找到一个特定的节点;解析器可以通过它找到我们已经指定的特定地标。

SAX(&#34; Simple API for XML&#34;)处理从文档流的顶部到结尾连续发生,并且当每个标记打开或关闭时,我们有机会对其参数做一些事情。我们不得不使用XPath或CSS选择器进行搜索,而是在获取标记打开事件时查找标记的名称,并设置标记以记住我们已经看到它,然后查找后续标记名称因为他们已经打开,直到我们达到所需的内容。

SAX是一种完全不同的处理文档的方式,但它的优点是它的内存效率更高。