2012-07-30 60 views
1

twig_handlers next_elt我還是新的使用XML::Twig無法使用NEXT_SIBLING的方法或使用XML ::嫩枝

從主程序我期待的元素與屬性@method="create"

在子程序player,我想找到屬性@method="modify"下一個元/兄弟。

這些方法都失敗子程序player與錯誤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 

例子:

<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

總是use strict在您的程序的頂部,並在第一次使用時使用my聲明變量。在use warnings-w命令行選項中都沒有意義。第一個是可取的。

當調用<middle method="create">元素的樹枝處理程序時,您需要的同級,<middle method="modify">尚未處理。它不能被找到,因爲它還沒有在XML::Twig解析樹中。

必須要麼讀取整個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樹,並從中提取後的數據。它開始通過尋找樹中的所有元素有method屬性等於'create',然後發現他們每個人以下的兄弟姐妹與'modify'一個method屬性。

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_handlers – laurentngu 2012-07-30 17:49:42

+1

我認爲你誤解了'XML :: Twig'的工作方式。在*每個*元素上設置句柄將需要大量的編碼,這幾乎肯定是不必要的。你的XML文件有多大?如果達到幾KB,那麼最好將整個結構讀入內存並從那裏處理。如果你解釋這個問題你必須解決,然後我們可以幫助進一步 – Borodin 2012-07-30 19:30:55

+0

所以twig_handlers(異步隊列)到「查詢每個搜索元素」將消耗更多的CPU /內存比「讀取整個文件+ get_xpath」(你的第二個解決方案) ?如果是的話,我會堅持你的第二個解決方案,並根據twig_handlers修改我以前的代碼。 – laurentngu 2012-07-30 23:05:14