【问题标题】:How to print values from separate XML Twig handlers如何从单独的 XML Twig 处理程序打印值
【发布时间】:2016-02-13 06:05:35
【问题描述】:

谁能帮我弄清楚如何在使用 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>

【问题讨论】:

  • 似乎不可能 - code 标签出现在 name 标签之后,您需要知道在名称标签处理程序中是打印 , 还是 \n。我想你应该删除你的处理程序并为child 添加一个。
  • @Kenny 我有一个非常大的文件,我认为放置“子”处理程序需要大量内存。
  • 如果它只是打印一些东西,那么它应该无关紧要。
  • 如果内存是一个问题,您可以尝试的一个“hack”是在处理之前转换 xml(可能使用 xslt)以交换名称和代码标签的顺序。然后,您需要将代码值保存到代码处理程序中的变量中,并且只在名称处理程序中打印它。
  • child 处理程序将仅在您进行清除时使用元素大小的内存。所以没关系。

标签: xml perl xml-twig


【解决方案1】:

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

因此,您可以使用的一种方法是在 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>

注意-正如您提到的一个大文件-上面的子处理程序调用purge,它丢弃了迄今为止处理的XML。这意味着它会丢弃已解析的 XML,从而减少内存占用。

【讨论】:

    猜你喜欢
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 2020-01-10
    相关资源
    最近更新 更多