2012-07-30 3 views
1

저는 XML::Twig을 사용하여 새롭습니다. 나는 서브 루틴 player에서 속성 @method="create"XML :: Twig를 사용하여 twig_handlers 메소드 next_sibling 또는 next_elt를 사용할 수 없습니다.

와 요소를 찾아 주 프로그램에서

, 나는 속성 @method="modify"다음 요소/형제를 찾고 싶어요. 이러한 방법의

오류 input.xwo의 Can't call method "gi" on an undefined value

my $modif1=$valeur->next_sibling('[@method="modify"]') 

my $modif2=$valeur->next_elt('[@method="modify"]')->parent 

예와 서브 루틴 player 실패 :

<top id="World"> 

    <middle id="France" method="create"> 
    </middle> 

    <middle id="Germany" method="modify"> 
    </middle> 

</top> 

내 간단한 코드 : 항상

#!/bin/perl -w 
use warnings; 
use XML::Twig; 

my $twig= new XML::Twig( 
    twig_handlers => { 
    '[@method="create"]' => \&player 
    } 
);      

$twig->parsefile("input.xwo"); 
$twig->purge; 

sub player { 

    my ($twig, $valeur) = @_;      

    my $modif1 = $valeur->next_sibling('[@method="modify"]'); 
    my $modif2 = $valeur->next_elt('[@method="modify"]')->parent; 
    print "\nnextELT=" . $modif->gi . "\n"; 
} 

답변

7

하십시오 프로그램 상단에을 삽입하고 첫 번째 사용 시점에 my을 사용하여 변수를 선언하십시오. use warnings-w 명령 줄 옵션에는 아무런 의미가 없습니다. 첫 번째가 바람직합니다.

<middle method="create"> 요소의 나뭇 가지 처리기가 호출되면 필요로하는 형제 인 <middle method="modify">이 처리되지 않았습니다. 아직 구문 트리에 있지 않기 때문에 찾을 수 없습니다.

당신은 전체 XML 구조를 읽고 나중에이를 처리, 또는 모두createmodify 요소를 둘러싸는 요소에 대한 처리기를 작성해야 하나.

이 프로그램은 후자를 수행합니다.

use strict; 
use warnings; 

use XML::Twig; 

my $twig= XML::Twig->new(
    twig_handlers => { 
    top => \&player 
    } 
);      

$twig->parsefile('input.xwo'); 
$twig->purge; 

sub player { 

    my ($twig, $valeur) = @_;     

    my $create = $valeur->first_child('[@method="create"]'); 
    return unless $create; 

    my $modify = $create->next_sibling('[@method="modify"]'); 
    return unless $modify; 

    printf "\nnextELT = %s\n", $modify->gi; 

    $twig->purge; 
} 

업데이트

이 대안은 전체 XML 트리를 읽고 나중에 그것에서 데이터를 추출합니다. 모든 요소가 인 'create' 인 트리를 찾은 다음 method 특성이 'modify' 인 다음 형제를 찾습니다.

use strict; 
use warnings; 

use XML::Twig; 

my $twig= XML::Twig->new; 

$twig->parsefile('input.xwo'); 

my @creates = $twig->get_xpath('//*[@method="create"]'); 

foreach my $create (@creates) { 
    my $modify = $create->next_sibling('[@method="modify"]'); 
    next unless $modify; 
    printf "\nnextELT = %s\n", $modify->gi; 
} 
+0

그 해결책에 대해 @Borodin에게 감사드립니다. 그러나'twig_handlers'를 이용한 해결책을 위해서 나무의 모든 요소를 ​​어떻게 찾을 수 있습니까? 작성한 코드에서 검색 할 첫 번째 분기로 'top'을 넣습니다. Twig_handler를 사용하여 모든 요소를 ​​찾아야합니다. – laurentngu

+1

'XML :: Twig'가 작동하도록 오해하고 있다고 생각합니다. 모든 * 요소에 핸들을 설정하면 거의 불필요한 많은 양의 코딩이 수반됩니다. XML 파일의 크기는 얼마입니까? 몇 KB에 이르면 전체 구조를 메모리로 읽어서 거기에서 처리하는 것이 가장 좋습니다. 해결해야 할 문제를 설명하면 – Borodin

+0

을 더 도울 수 있으므로 twig_handlers (비동기 대기열)에서 "각 검색 요소 쿼리"를 사용하면 "전체 파일 + get_xpath"(두 번째 솔루션)보다 CPU/메모리가 많이 소모됩니다. ? 그렇다면 두 번째 해결책을 고수하고 twig_handlers를 기반으로 이전 코드를 수정합니다. – laurentngu