如何使用Perl从目录中的多个XML文件创建一个XML文件

时间:2011-11-18 18:17:52

标签: xml perl perl-module

大家好,
如果有任何语法错误,请原谅  我在一个目录中有多个xml文件,我需要在一个XML文件中创建多个XML文件。像这样的示例文件

  file1:bvr.xml

<?xml version="1.0" encoding="UTF-8"?>
<specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <details>
 <name>johan</name>
 <address>Langgt 23</address>
  ---more info---
 </details>
</specification>

 file2:kvr.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <details>
 <name>venu</name>
 ---more info---
 </details>
 </specification>

   file3:svr.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <details>
 <name>kent</name>
 ---more info----
  </details>
  </specification>

  file4:tvr.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <definition>
 <name>kent</name>
  ----more info---
  </definition>
  </specification>

我需要像这样创建一个xml文件。

       new.xml 

<?xml version="1.0" encoding="UTF-8"?>
<specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <details>
 <name>johan</name>
 <address>Langgt 23</address>
  --more info--
 </details>

 <details>
 <name>venu</name>
 ---more info----
 </details>

 <details>
 <name>kent</name>
 <address>vadrss 25</address>
 ---more info--
  </details>

   <definition>
 <name>kent</name>
  ----more info----
  </definition>
</specification>

我试过这样但是我对这个脚本有一些问题。

#!/usr/bin/perl
  use warnings;
  use strict;
 use File::Find;
   use XML::LibXML::Reader;
 use Data::Dumper;
  my $Number;

  my $dir="C:/file/sav";
  find(\&wanted, $dir);
  sub wanted() {
       if ( -f and /(\.xml)$/) {# find all the files with a suffix of .xml

  my $reader = XML::LibXML::Reader->new( location =>$_ )
 or die "cannot read file.xml\n";

    while ($reader->nextElement( 'details' ) ){

          $Number = $reader->readOuterXml();

          print "$Number\n";    
             } 

         }
   return;                   
  }

但我在这个剧本中有两个问题

1)我从所有XML文件中提取信息具有“详细信息”节点元素,但在一个XML文件中我有一些其他节点元素“定义”的数据我没有提取该信息,如果我想要怎么办?提取该信息并存储在同一个变量中。

2)在提取存储在$Number变量中的所有信息之后,我想将$Number变量信息存储在一个XML文件中,我该怎么做呢?请帮助我。我是perl的新手。

                    (or)

是否有其他方法可以将所有XML文件数据合并到一个XML文件中。

在您尝试使用代码之后,它会提供更多错误

#!/usr/bin/perl
use warnings;
use strict;
  use XML::LibXML;
my @xml_files = glob '*.xml';
my $bigXML = XML::LibXML::Document->new( '1.0', 'UTF-8');
my $aggregated; for my $xml_file ( @xml_files ) {

my $doc = XML::LibXML->new->parse_file( $xml_file );

my ( $specNode ) = $doc->findnodes( '//Specification' );

  if ( $aggregated ) {
 $aggregated = $specNode;
 }
 else {
 my @details = $specNode->findnodes( './details' );
 $aggregated->addChild( $_ ) foreach @details;
 }
  }
  $bigXML->adoptNode( $aggregated ); 
 $bigXML->toFile( 'aggregated_data.xml' );

它给出了我在can't call method "findnodes" on an undefined value之前提出的相同的错误,我试图在详细信息行中使用斜杠重复点,同时也给出相同的错误。

如果尝试使用像这样的golb函数

my @xml_files = glob '*dtc.xml';

在上面的代码中这次给出了不同的错误,如

XML::LibXML::Document::adoptNode()-- Node is not a blessed SV reference at line 21

我正在努力解决这些错误,因为这对我来说是一个非常新的模块,而且我查看了该文档,每个东西都是正确的格式,但我无法理解这些错误。我是这个perl的初学者,可以帮助我。

1 个答案:

答案 0 :(得分:1)

首先,感谢您在此发布您的工作并说明您最终想要做的事情,即将所有XML合并到一个文件中。

解决问题的需要:

  1. use strict; use warnings;

    抓住愚蠢的错误并执行良好的错误处理

  2. use XML::LibXML;

    使用您的解析器

  3. my @xml_files = glob '*.xml';

    查找目录中的所有XML文件

  4. my $bigXML = XML::LibXML::Document->new( '1.0', 'UTF-8');

    实例化将存储所有节点的大XML。

  5. 遍历每个文件,获取节点并将节点推送到聚合节点

    my $ aggregated; 对于我的$ xml_file(@xml_files){

    my $doc = XML::LibXML->new->parse_file( $xml_file );
    
    my ( $specNode ) = $doc->findnodes( '//specification' );
    
    if ( ! $aggregated ) {        # Initialize if doesn't exist
    
        $aggregated = $specNode;
    }
    
    else {                        # Add more <details>
    
        my @details = $specNode->findnodes( './details' );
        $aggregated->addChild( $_ ) foreach @details;
    }
    

    }

  6. $aggregated节点添加到$bigXML文档并打印:

    $bigXML->addChild( $aggregated ); $bigXML->toFile( 'aggregated_data.xml' );