2015-01-06 2 views
-1

Я как-то застрял и стучал головой. Мне нужно удалить нежелательные TRADES из огромного XML-файла.XML :: TWIG для фильтрации XML в PERL

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

Теперь, вторая ТОРГОВЛЯ оказывает externtype = внутренний узел 'PROCC', который не является законным (легитимным значение 'PROC')

Следовательно, конечный результат должен быть

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

который должен быть вставлен в новый файл. Наиболее важным моментом, который следует отметить здесь, является то, что одно СОБЫТИЕ имеет незаконную ценность, поскольку другое 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 тега вместо ТОРГОВЫЙ тегу.

Подсказка будет оценена по достоинству.

+0

Пожалуйста, разместите хорошо сформированный XML. – toolic

+0

извините ... будет иметь в виду в будущем –

ответ

0

Я не знаю XML :: Twig. В XML :: Libxml, вы могли бы сделать

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

Вам нужно сделать $TRADE->cut вместо $c->cut. Однако, так как ваше условие находится на $c, вы можете сделать следующее:

sub TRADE { 

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

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

Zaid, Так мило с вашей стороны за ваш неоценимый вклад. На самом деле FIRST_CHILD не поможет, потому что несколько СОБЫТИЙ могут находиться внутри одной TRADE ... Извините за отсутствие этого в моем quetion..Hence, если сначала EVENT не удовлетворяет условию, тогда как второе EVENT удовлетворяет. законным. Короче, даже одно из СОБЫТИЙ внутри любой TRADE удовлетворяет условию, тогда TRADE должен быть выбран. –

+0

@vikas: подход остается таким же; просто чтобы условие было обновлено, чтобы перебрать все узлы EVENT и посмотреть, есть ли у какого-либо из них атрибут с указанным значением. – Zaid

+0

Большое спасибо за ваши усилия. Над фрагментом кода копируется только те TRADES в новый файл, который вообще не имеет «PROC» под любым событием. В то время как я хотел наоборот. Я попробовал «ne» вместо «eq», но безрезультатно. Пожалуйста, дайте свое понимание –