XML :: TWIG过滤PERL中的XML

时间:2015-01-06 14:45:32

标签: perl xml-twig

我不知怎的被困住了。 我必须从一个巨大的XML文件中删除不需要的TRADES。

<TRADEEXT>
  <TRADE origin = 1,version =1>
     <EVENT externtype ='PROC'/>
     <EVENT externtype ='PROCC'/>
  </TRADE>
  <TRADE origin = 1,version =1>
     <EVENT externtype ='PROCC'/>
  </TRADE>
</TRADEEXT>

现在,第二个交易所是externtype =&#39; PROCC&#39;内部节点不合法(合法值是&#39; PROC&#39;)

因此最终输出应为

<TRADEEXT>
   <TRADE origin = 1,version =1>
      <EVENT externtype ='PROC'/>
      <EVENT externtype ='PROCC'/>
   </TRADE>
<TRADEEXT>

应该粘贴到新文件。这里要注意的最重要的一点是即使一个EVENT具有非法价值,因为另一个EVENT具有合法价值,TRADE变得合法。 因此,至少有一个EVENT应该是合法的,这将使整个贸易合法化 我的代码是

use strict;
use warnings;
use XML::Twig;

my $twig = new XML::Twig( twig_handlers => { TRADE => \&TRADE } );
$twig->parsefile('1513.xml');
$twig->set_pretty_print('indented');
$twig->print_to_file('out.xml');

sub TRADE {
    my ( $twig, $TRADE ) = @_;
    foreach  my $c ($TRADE->children('EVENT')) 
    {
     $c->cut($TRADE) unless
     $c->att('eventtype') eq "PROC"

      ;
    }
}

不幸的是,它删除了EVENT标记而不是TRADE标记。

任何提示都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

您需要$TRADE->cut代替$c->cut。但是,由于您的条件是$c,因此您可能需要执行以下操作:

sub TRADE {

    my ( $node, $TRADE ) = @_ ;

    $TRADE->cut
      unless grep { $_->att( 'eventtype' ) eq 'PROC' } $TRADE->children( 'EVENT' );
}

答案 1 :(得分:0)

我不知道XML :: Twig。在XML :: LibXML中,你要做

for my $bad_trade ('/TRADEEXT/TRADE[ EVENT/@externtype = "PROCC" ]') {
    $bad_trade->parentNode->removeChild($bad_trade);
}