如何从单独的XML Twig处理程序中打印值

时间:2015-11-12 00:42:28

标签: xml perl xml-twig

任何人都可以帮我弄清楚如何在使用XML Twig使用以下代码在文件中打印之前检查标签是否存在:

open my $file, '>', "output.txt";

#parse the record
my $t= XML::Twig->new(twig_roots => { 
    'parent/child/code' => \&code,
    'parent/child/name' => \&name,

 });
$t->parsefile("test.xml");

sub name { 
    my($t, $elt)= @_; 
    $n = $elt->text; 
    print $file "$n,";  
    $t->purge; 
}

sub code { 
    my($t, $elt)= @_; 
    $a = $elt->first_child->att('c'); 
    print $file "$a\n"; 
    $t->purge; 
}

我想检查是否存在<code>标记,并在文本文件中以格式化方式打印它。

我在输出文件中使用上面的代码获取了后续内容:

Alex,001
Ryan,Nicole,003

但我希望能够获得所需的输出:

Alex,001
Ryan
Nicole,003

的test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <child>
        <name>Alex</name>
        <code c="001">001AB</code>
    </child>
    <child>
        <name>Ryan</name>
    </child>
    <child>
        <name>Nicole</name>
        <code c="003">001XC</code>
    </child>
</parent>

1 个答案:

答案 0 :(得分:0)

你不能使用处理程序,因为处理程序可以“随时”运行 - 它会在“看到”一个关闭标记时触发,因此你在解析时没有看到你需要的数据。

因此,您可以使用的一种方法是在child上设置处理程序:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;
use XML::Twig;

sub handle_child_elt {
  my ( $twig, $child ) = @_; 

  print "Name: ", $child -> first_child_text('name'),"\n";
  if ( $child -> first_child('code') ) {
      print "Code: ", $child -> first_child('code') -> att('c'),"\n";
  }
   $twig -> purge; 
}

XML::Twig -> new ( twig_handlers => { 'child' => \&handle_child_elt } ) -> parse ( \*DATA ); 

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <child>
        <name>Alex</name>
        <code c="001">001AB</code>
    </child>
    <child>
        <name>Ryan</name>
    </child>
    <child>
        <name>Nicole</name>
        <code c="003">001XC</code>
    </child>
</parent>

注意 - 当你提到一个大文件时 - 上面的子处理程序调用{​​{1}}到目前为止丢弃已处理的XML。这意味着它会抛弃已解析的XML,从而减少内存占用。