无法使用XML :: Twig将方法next_sibling或next_elt与twig_handlers一起使用

时间:2012-07-30 16:37:31

标签: perl xml-parsing xml-twig

我仍然使用XML::Twig

在主程序中,我查找属性为@method="create"

的元素

在子例程player中,我想找到属性为@method="modify" next 元素/兄弟。

这两种方法都失败了子程序player,错误为Can't call method "gi" on an undefined value

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

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

input.xwo示例:

<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";
}

1 个答案:

答案 0 :(得分:7)

始终 use strict位于程序顶部,并在首次使用时使用my声明变量。 use warnings-w命令行选项都没有意义。第一个是可取的。

当调用<middle method="create">元素的twig处理程序时,您所需的兄弟<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'所有元素,然后使用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;
}