Как искать XML при разборе с использованием SAX в nokogiri - PullRequest
4 голосов
/ 27 декабря 2010

У меня есть простой, но огромный XML-файл, как показано ниже. Я хочу разобрать его с помощью SAX и распечатать только текст между тегами title.

<root>
    <site>some site</site>
    <title>good title</title>
</root>

У меня есть следующий код:

require 'rubygems'
require 'nokogiri'
include Nokogiri

class PostCallbacks < XML::SAX::Document
  def start_element(element, attributes)
    if element == 'title'
      puts "found title"
    end
  end

  def characters(text)
    puts text
  end
end

parser = XML::SAX::Parser.new(PostCallbacks.new)
parser.parse_file("myfile.xml")

Проблема в том, что он печатает текст между всеми тегами. Как я могу просто напечатать текст между тегом title?

Ответы [ 2 ]

8 голосов
/ 27 декабря 2010

Вам просто нужно отслеживать, когда вы находитесь внутри <title>, чтобы characters знал, на что следует обратить внимание.Что-то вроде этого (непроверенный код), возможно:

class PostCallbacks < XML::SAX::Document
  def initialize
    @in_title = false
  end

  def start_element(element, attributes)
    if element == 'title'
      puts "found title"
      @in_title = true
    end
  end

  def end_element(element)
    # Doesn't really matter what element we're closing unless there is nesting,
    # then you'd want "@in_title = false if element == 'title'"
    @in_title = false
  end

  def characters(text)
    puts text if @in_title
  end
end
1 голос
/ 28 февраля 2013

Принятый выше ответ является правильным, однако у него есть недостаток, что он будет проходить через весь XML-файл, даже если он обнаружит <title> в самом начале.

У меня были аналогичные потребности, и я закончилнаписание saxy рубинового камня, который призван быть эффективным в таких ситуациях.Под капотом реализован SAX Api от Nokogiri.

Вот как бы вы его использовали:

require 'saxy'
title = Saxy.parse(path_to_your_file, 'title').first

Он остановится, когда обнаружит первое вхождение тега <title>.

...