如何将两个XML文件与Perl结合使用?

时间:2009-07-02 13:07:52

标签: xml perl

我想将多个XML文件合并到Perl中的单个XML文件中。

文件1:

<r1>
   <searchpath>
     <dir>/usr/bin</dir>
     <dir>/usr/local/bin</dir>
     <dir>/usr/X11/bin</dir>
   </searchpath>
 </r1>

文件2:

<r2>
  <user login="grep" fullname="Gary R Epstein" />
  <user login="stty" fullname="Simon T Tyson" />
</r2>

合并文件

<XML>
      <r1>
       <searchpath>
         <dir>/usr/bin</dir>
         <dir>/usr/local/bin</dir>
         <dir>/usr/X11/bin</dir>
       </searchpath>
     </r1>
     <r2>
          <user login="grep" fullname="Gary R Epstein" />
          <user login="stty" fullname="Simon T Tyson" />
        </r2>
</XML>

4 个答案:

答案 0 :(得分:6)

#!/usr/bin/perl

use strict;
use warnings;
use XML::LibXML;

my $parser = XML::LibXML->new();
my $xml1 = $parser->parse_string( <<'XML' );
<r1>
   <searchpath>
     <dir>/usr/bin</dir>
     <dir>/usr/local/bin</dir>
     <dir>/usr/X11/bin</dir>
   </searchpath>
 </r1>
XML

my $xml2 = $parser->parse_string( <<'XML' );
<r2>
  <user login="grep" fullname="Gary R Epstein" />
  <user login="stty" fullname="Simon T Tyson" />
</r2>
XML

my $new_xml = XML::LibXML::Element->new( 'XML' );
$new_xml->appendWellBalancedChunk( $xml1->documentElement()->toString() );
$new_xml->appendWellBalancedChunk( $xml2->documentElement()->toString() );
print $new_xml->toString(1);

如果您的数据是文件而不是字符串,您还可以使用$ parser-&gt; parse_file($ filename)(参见perldoc XML :: LibXML :: Parser)。

$ new_xml-&gt; toString(1)中的1是正确缩进输出。有关该信息,请参阅perldoc XML :: LibXML :: Node。

在这里分叉:http://github.com/robinsmidsrod/xml-merge

答案 1 :(得分:2)

#!/usr/bin/perl
print  '<xml>';
print while <>;
print '</xml>';

答案 2 :(得分:1)

首先按顺序对文件进行排序,然后打开所有文件并读取每个文件的第一条记录。然后扫描每个文件的记录以找到第一个文件。然后读取该文件的下一条记录。重复直到完成。

答案 3 :(得分:1)

编辑来自提问者的新信息。

如果您只想处理所有这些文件的内容,这应该有效:

@ARGV = qw<F1 f2 f3 f4>;
print "<XML>\n";
while ( my $line = <> ) { 
   print "    $line";
}
print "</XML>\n";

当然,你可以把文件放在一起,如果你不像XML那样关心缩进 - 并用“\ n”......“\ n”将其粘贴。


如果需要,当前文件的名称将在$ARGV中。当前记录的数量为$.(或通过英语:$NR$INPUT_LINE_NUMBER

合并

如果您要合并文件,则需要对它们进行排序(File::Sort)。然后,您需要为要合并的所有文件提供专用缓冲区,并根据排序方案扫描最低记录。如果选择该缓冲区,请从该文件中刷新它,然后处理缓冲区。

这些步骤是:

  1. 以连接顺序首先选择
  2. 从相应文件刷新,标记为EOF
  3. 流程记录
  4. 我会创建一个Buffer以及BufferSet类来封装此功能。 Buffer知道如何在被询问时提供当前记录,并在选择时从其IO源刷新。 BufferSet知道从其Buffer对象列表中查找下一条记录并处理Buffer个对象。 BufferSet对象肯定应该知道排序顺序,它也可以处理确保任何缓冲区已经排序的工作。

    如果您想这样做,可以使用Class::Delegator使BufferSet的行为类似于直接IO对象。