Sax用nokogiri解析奇怪的元素

时间:2012-04-02 22:18:57

标签: ruby nokogiri sax

我想在nokogiri中进行sax-parse,但是当涉及到解析xml元素时,它会有一个长而疯狂的xml元素名称或属性...然后everthing变得疯狂。

Fore instans如果我想解析这个xml文件并获取所有title元素,我该怎么做nokogiri-sax。

<titles>
    <title xml:lang="sv">Arkivvetenskap</title>
    <title xml:lang="en">Archival science</title>
</titles>

1 个答案:

答案 0 :(得分:4)

在您的示例中,title是元素的名称。 xml:lang="sv"是一个属性。 此解析器假定没有嵌套在title元素中的元素

require 'rubygems'
require 'nokogiri'

class MyDocument < Nokogiri::XML::SAX::Document
  def start_element(name, attrs)
    @attrs = attrs
    @content = ''
  end
  def end_element(name)
    if name == 'title'
      puts Hash[@attrs]['xml:lang']
      puts @content.inspect
      @content = nil
    end
  end
  def characters(string)
    @content << string if @content
  end
  def cdata_block(string)
    characters(string)
  end
end

parser = Nokogiri::XML::SAX::Parser.new(MyDocument.new)
parser.parse(DATA)

__END__
<titles>
    <title xml:lang="sv">Arkivvetenskap</title>
    <title xml:lang="en">Archival science</title>
</titles>

打印

sv
"Arkivvetenskap"
en
"Archival science"

SAX解析通常过于复杂。因此,我推荐Nokogiri的标准内存解析器,或者如果你真的需要速度和内存效率,Nokogiri's Reader parser

为了比较,这里是同一文件的标准Nokogiri解析器

require 'rubygems'
require 'nokogiri'

doc = Nokogiri::XML(DATA)
doc.css('title').each do |title|
  puts title['lang']
  puts title.text.to_s.inspect
end

__END__
<titles>
    <title xml:lang="sv">Arkivvetenskap</title>
    <title xml:lang="en">Archival science</title>
</titles>

这是同一文档的读者解析器

require 'rubygems'
require 'nokogiri'

reader = Nokogiri::XML::Reader(DATA)
while reader.read
  if reader.name == 'title' && reader.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
    puts reader.attribute('xml:lang')
    puts reader.inner_xml.inspect # TODO xml decode this, if necessary.
  end
end

__END__
<titles>
    <title xml:lang="sv">Arkivvetenskap</title>
    <title xml:lang="en">Archival science</title>
</titles>