2011-11-21 77 views
1

我編寫了一個腳本,它可以從多個文件創建一個xml文件,我這樣寫腳本。如何向xml文件添加更多節點信息

#!/usr/bin/perl 
use warnings; 
use strict; 
use XML::LibXML; 
use Carp; 
use File::Find; 
use File::Spec::Functions qw(canonpath); 
use XML::LibXML::Reader; 
use Digest::MD5 'md5'; 

if (@ARGV == 0) { 
push @ARGV, "c:/main/work"; 
warn "Using default path $ARGV[0]\n Usage: $0 path ...\n"; 
} 

open(my $allxml, '>', "all_xml_contents.combined.xml") 
or die "can't open output xml file for writing: $!\n"; 
print $allxml '<?xml version="1.0" encoding="UTF-8"?>', 
"\n<Shiporder xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"; 
my %shipto_md5; 
find(
sub { 
    return unless (/(_stc\.xml)$/ and -f); 
    extract_information(); 
    return; 
}, 
@ARGV 
); 

print $allxml "</Shiporder>\n"; 

sub extract_information { 
my $path = $_; 
if (my $reader = XML::LibXML::Reader->new(location => $path)) { 
    while ($reader->nextElement('data')) { 
     my $elem = $reader->readOuterXml(); 
     my $md5 = md5($elem); 
     print $allxml $reader->readOuterXml() unless ($shipto_md5{$md5}++); 
    } 
    } 
return; 
} 

從上面的腳本我從所有xml文件中提取數據節點信息並存儲在一個新的xml文件中。但我還有一個節點與「細節」,我需要提取的信息開始,我還需要補充的是信息的文件,我想這樣的

$reader->nextElement('details'); 
    my $information = $reader->readOuterXml(); 

我說這while循環,但如何能我將這些數據分配或打印到同一個文件($ all xml)。請幫我解決這個問題。

你的建議,我想是這樣後,它給錯誤

#!/usr/bin/perl 
    use warnings; 
    use strict; 
    use XML::LibXML; 
    use Carp; 
    use File::Find; 
    use File::Spec::Functions qw(canonpath); 
    use XML::LibXML::Reader; 
    if (@ARGV == 0) { 
    push @ARGV, "V:/main/work"; 
warn "Using default path $ARGV[0]\n Usage: $0 path ...\n"; 
    } 

    my $libXML = new XML::LibXML; 
    my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?  
    >','<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'); 
    my $shiporder = $outputDom->documentElement; 

    find(
    sub { 
    return unless (/(_stc\.xml)$/ and -f); 
    extract_information(); 
    return; 
    }, 
    @ARGV 
); 
sub extract_information { 
    my $path = $_; 
if(my @inputDom = XML::LibXML->load_xml(location => $path)){ 
$inputDom->findnodes('//data || //deatils'); 
foreach (@$inputDom) { 
    $shiporder->appendChild($_->parentNode->cloneNode(1)); 
} 
    $outputDom->toFile("allfiles.xml"); 
    } 
    } 

但它給像 「 '\ n \ N:1:分析器錯誤:Strat的標記預期,' <」找不到「 你能用腳本幫助我,因爲我對perl非常陌生。

回答

1

如果您使用了XML :: LibXML和相關模塊爲您提供的功能,您會做得更好,這是一個非常龐大而全面的模塊,可以讓您在幾行內完成很多工作。

您可以使用解析器使用parse_string啓動新的dom文檔,使用documentElement存儲根節點。從那裏,使用parse_file加載每個輸入文件,然後在輸入文件上找到節點以提取要克隆的節點。然後將輸入節點的克隆附加到輸出文檔,最後使用toFile方法寫出輸出。

喜歡的東西:

my $libXML = new XML::LibXML; 
my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?>', 
'\n<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n'); 
my $shiporder = $outputDom->documentElement; 

... 

my $inputDom = $libXML->parse_file(some_file_name); 
$inputDom->findnodes('//data || //details'); # use a more suitable xpath 
foreach (@$inputDom) { 
    $shipOrder->appendChild($_->parentNode->cloneNode(1)); # if you want parent too... 
} 

... 

$outputDom->toFile(some_output_file); 

}

你必須允許命名空間和諸如此類的東西,但是這給一個方法開始。

+0

我是新來的perl,我試着按照你說的,我發佈了我在我的問題上試過的東西,你可以看看並幫助我。 – biji

+1

我的例子只是一個指導。由於\ n在單引號內,您可能會遇到錯誤。單引號可防止perl插值。 – mvsjes2

+0

由於您使用的是parse_string,因此您可以一起刪除新行,因爲解析器只會將它們視爲空白區域。 – mvsjes2