2010-12-27 2 views
4

다음과 같이 간단하지만 거대한 XML 파일이 있습니다. SAX를 사용하여 구문 분석하고 title 태그 사이의 텍스트 만 인쇄하고 싶습니다.nokogiri에서 SAX를 사용하여 XML을 파싱 할 때 XML을 검색하는 방법

<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 태그 사이에 텍스트를 인쇄하는 방법은 무엇입니까?

+0

"거대한"크기는 어느 정도입니까? 내 컴퓨터에서 사용 가능한 RAM보다 큰 파일을 가지고 있기 때문에 SAX를 사용했지만, 요즘에는 RAM을 사용할 수 있으므로 일반적으로 DOM을 사용하여 구문 분석합니다. –

+0

이 질문을 제기 해 주셔서 감사합니다. – Aditya1510

답변

8

<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 
+0

좋은 답변, +1 :) –

+0

하루에 +1했습니다. – Aditya1510

1

그러나 그것이 바로 시작 부분에 <title>를 발견하더라도 그것은 전체 XML 파일을 통해 갈 것이라는 단점이있다.

나는 비슷한 요구를 가지고 있었고 그러한 상황에서 효율적으로하기 위해 만들어진 saxy 루비 보석을 작성했다. 후드 아래에는 Nokogiri의 SAX Api가 구현됩니다. 여기

당신이 그것을 사용하는 거라고 방법은 다음과 같습니다가 <title> 태그의 첫 번째 항목을 발견하면

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

그것은 바로 정지됩니다.