2013-04-16 133 views
2

嗨,我有一个XML,我希望根据其中的标记值将其拆分为多个XML。基于标记值拆分XML

实施例: -

<HEADER> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>78011DAC8</TAG2> 
<TAG3>US78011DAC83</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>78011DAD6</TAG2> 
<TAG3>US78011DAD66</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>B06983611</TAG2> 
<TAG3>GB0009075325</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>B06983629</TAG2> 
<TAG3>GB0009081828</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>BRS038D62</TAG2> 
<TAG3>FR0010050559</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>ABC</TAG1> 
<TAG2>BRS49ESZ5</TAG2> 
<TAG3>GB00B1Z5HQ14</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>B06983637</TAG2> 
<TAG3>GB0008983024</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS26Y2R4</TAG2> 
<TAG3>GB00B128DH60</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS1JW2X3</TAG2> 
<TAG3>FR0010235176</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS1JW2Y1</TAG2> 
<TAG3>GB00B0CNHZ09</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS3BP9P2</TAG2> 
<TAG3>GB00B1L6W962</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS7FFAV6</TAG2> 
<TAG3>GB00B3D4VD98</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>B0A07E1X7</TAG2> 
<TAG3>GB0031790826</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>DEF</TAG1> 
<TAG2>BRS1Z0T57</TAG2> 
<TAG3>GB00B0V3WQ75</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>XYZ</TAG1> 
<TAG2>BRS9ZDYJ6</TAG2> 
<TAG3>FR0010899765</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>XYZ</TAG1> 
<TAG2>BRS8ANE14</TAG2> 
<TAG3>DE0001030526</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>XYZ</TAG1> 
<TAG2>BRS22TXL8</TAG2> 
<TAG3>DE0001030500</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>XYZ</TAG1> 
<TAG2>BRS5LHPB7</TAG2> 
<TAG3>GB00B24FFM16</TAG3> 
</ROOT> 
<ROOT> 
<TAG1>XYZ</TAG1> 
<TAG2>B06983223</TAG2> 
<TAG3>GB0008932666</TAG3> 
</ROOT> 
</HEADER> 

在上述例子中,我需要检查TAG1值,并且如果它与下一个TAG1值匹配它不应该分裂,如果不匹配,那么它应该分成一个新的XML文件...

感谢您的帮助!

+1

[你尝试过什么?](HTTP:/ /mattgemmell.com/2008/12/08/what-have-you-tried/) – Demnogonis

回答

0

也许你可以用

use XML::Simple; 

my $xml = XMLin($your_xml); 

,然后一些分析它像

if ($xml->{HEADER}->[0]->{ROOT}->{TAG1} == $xml->{HEADER}->[1]->{ROOT}->{TAG1}) { ... } 

我居然不知道outcoming XML STRUC

+0

输出应根据TAG1值拆分为多个xml ...因为TAG1值是前6条记录的ABC ..这些6记录应写入一个新的XML文件名,扩展名为Part1左右......并且由于TAG1的值对于后面的8条记录是不同的,所以这8条记录应该包含xml文件名part2,等等.... – Srini

2

这是一个比较简单的方法来做到这一点使用XML ::嫩枝。保存在内存中的最大容量是一个完整的子文件,以防万一这一点很重要(可能会做得更好,最多只能保留1个内存)。

#!/usr/bin/perl 

use strict; 
use warnings; 

use autodie qw(open); 

use XML::Twig; 

my $in_file = $ARGV[0]; 

my $out_file= "$in_file.p"; 
my $i="01"; 
my $current_tag1=''; 


my $twig=XML::Twig->new( 
    twig_handlers => { 
     ROOT => sub { my($t, $root)= @_; 
        $current_tag1||= $root->field('TAG1');  # initialize current tag if needed 

        if($root->field('TAG1') ne $current_tag1) # found a break in the value of TAG1 
         { 
         $root->cut;        # get the new root out of the way 
         $t->print_to_file($out_file. $i++);  # output the part 
         $t->purge;        # remove the content of the part 
         $root->paste(first_child => $t->root); # put the new root back in place 

         $current_tag1= $root->field('TAG1'); 
         } 
        } 
    }, 
    keep_spaces => 1, # to keep line returns 
); 

$twig->parsefile($in_file); 
$twig->print_to_file($out_file . $i); # output the last part 
+0

谢谢mirod ..这个脚本能够分割基于TAG1值的文件,但我想根据一些记录数(例如3)拆分XML文件,并检查TAG1值为直接记录,如果它匹配,则不会中断即使记录计数为3.只有在找不到相同的TAG1值后才停止...在我们的示例中,TAG1值是前5条记录的ABC,因此第一个part1 xml文件应该有5条记录(即使我们检查计数3条记录)等等。 – Srini

+0

文件的分割在处理程序中的if块内完成。这不会改变。您需要找到触发拆分的正确条件。我认为如果你为每个ROOT元素添加一个递增的计数器,并且在分割时重置,那么正确的条件将是当前的AND'$ counter'> $ MIN_ROOT_IN_FILE。你已经80%的勇气! – mirod

+0

感谢您的更新mirod。这里的问题是在if循环我无法重置值达到最大或最小记录值...可以帮助添加此条件与TAG1值检查...非常感谢... – Srini

2

Atlast我发现修复..下面 是将检查这两个计数和标签值的代码....

#!/usr/bin/perl 

use strict; 
use warnings; 

use autodie qw(open); 

use XML::Twig; 

my $in_file = $ARGV[0]; 

my $out_file= "$in_file.p"; 
my $i="01"; 
my $current_tag1=''; 
my $previous_tag1 = ''; 
my $nb_root_in_file =0; 
my $MIN_ROOT_IN_FILE = 5; 


my $twig=XML::Twig->new( 
twig_handlers => { 
    ROOT => sub { my($t, $root)= @_; 
    $current_tag1||= $root->field('TAG1');  # initialize current tag if needed 
    $nb_root_in_file++; 
    if($nb_root_in_file > $MIN_ROOT_IN_FILE && $root->field('TAG1') ne $current_tag1) # found a break in the value of TAG1 
        { 
        $root->cut;     # get the new root out of the way 
        $t->print_to_file($out_file. $i++);  # output the part 
        $t->purge;      # remove the content of the part 
       $root->paste(first_child => $t->root); # put the new root back in place 
        $current_tag1= $root->field('TAG1'); 
        $nb_root_in_file =0; 
        } 
        $previous_tag1 = $current_tag1; 
       } 
}, 
keep_spaces => 1, # to keep line returns 
); 

$twig->parsefile($in_file); 
    $twig->print_to_file($out_file . $i); # output the last part