2015-12-24 4 views
0

У меня есть два огромных файла XML (> 50M) и хотел бы добавить дерево узлов из одного XML в другой.XML :: twig для копирования дерева узлов из одного файла в другой

test1.xml

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<blocks> 
    <block name="block1" id="1"> 
     <lotsofcontents/> 
    </block> 
    <block name="block3" id="3"> 
      <lotsofcontents /> 
    </block> 
</blocks> 
</root> 

test2.xml

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<blocks> 
    <block name="block2" id="2"> 
     <lotsofcontents/> 
    </block> 
    <block name="block4" id="4"> 
      <lotsofcontents /> 
    </block> 
</blocks> 
</root> 

Я хотел бы, чтобы скопировать все блоки из test2.xml в test1.xml, так что результат выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<blocks> 
    <block name="block1" id="1"> 
     <lotsofcontents/> 
    </block> 
    <block name="block3" id="3"> 
     <lotsofcontents/> 
    </block> 
    <block name="block2" id="2"> 
     <lotsofcontents/> 
    </block> 
    <block name="block4" id="4"> 
     <lotsofcontents/> 
    </block> 
</blocks> 
</root> 

Я пробовал с кодом XML Twig, как показано ниже:

combine.pl

use strict; 
use XML::Twig; 

my $testa = "test1.xml"; 
my $testb = "test2.xml"; 
my $result = "result.xml"; 
my $MDTAG = "block"; 

my @blocks; 

my $twig = XML::Twig->new(twig_handlers => { 
              $MDTAG => sub {push @blocks; $_->cut_children; }, 
             }, 
         pretty_print => 'indented', 
         empty_tags => 'expand', 
        ); 
$twig->parsefile($testb); 

my $phere = XML::Twig->new(twig_handlers => { 
              $MDTAG => sub { foreach my $block (@blocks) 
                { $block->paste(first_child => $_); } }, 
             }, 
         pretty_print => 'indented', 
        ); 
$phere->parsefile($testa); 
$phere->print_to_file($result); 

Я получаю предупреждение, как показано ниже, и result.xml получает порождена, но ничего из test2.xml не добавляемый.

Useless use of push with no values at combine.pl line 16. 
Use of tied on a handle without * is deprecated at /opt/perl/lib/XML/Parser/Expat.pm line 447. 
Use of tied on a handle without * is deprecated at /opt/perl/lib/XML/Parser/Expat.pm line 447. 

Оценка за любые исправления и комментарии.

ответ

1

Я думаю, для основного документа вам нужно настроить обработчик для элемента blocks, а не для каждого элемента block.

С

use strict; 
use XML::Twig; 

my $testa = "test2015122401.xml"; 
my $testb = "test2015122402.xml"; 
my $result = "result2015122401.xml"; 

my @blocks; 

my $t1= XML::Twig->new( 
     twig_handlers => { 'block' => sub { push @blocks, $_; $_->cut(); }} 
        ); 
$t1->parsefile($testb); 


my $phere = XML::Twig->new(twig_handlers => { 
              '/root/blocks' => sub { 
               foreach my $block (@blocks) { 
               $block->paste(last_child => $_); 
               } 
              } 
             }, 
         pretty_print => 'indented', 
        ); 
$phere->parsefile($testa); 
$phere->print_to_file($result); 

я получаю результат, который вы хотите для образцов вы вывешенные.