2011-11-21 47 views
1

我有一個文件夾中的多個XML文件,所以我這樣寫的腳本結合成一個XML文件如何用perl

#!/usr/bin/perl 
use warnings; 
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像消除XML文件中的標記名稱這個。

all_xml.combined.xml 
<?xml version="1.0" encoding="UTF-8"?> 
<student specification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<student> 
<name>johan</name> 
</student> 

<student> 
<name>benny</name> 
</student> 

<student> 
<name>kent</name> 
</student> 

</student specification> 

,但我有一個XML文件多了一個節點的信息,我試圖提取像這樣的信息,while循環。

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

但是我如何將這些信息添加到輸出文件,請幫我解決這個問題。

+0

這是因爲http://stackoverflow.com/q/8187077/133939 – Zaid

回答

3

三個明顯的觀點。

  1. 您正在加載XML :: LibXML模塊,但未對其進行任何使用。
  2. 有問題的XML聲明始終是輸入文件的第一行。那麼爲什麼不跳過第一行?
  3. 您將以最終的文件將不是有效的XML。一個XML文檔需要一個根元素。因此,您需要創建另一個元素(可能是< students>),其中包含來自其他文件的所有數據。
+0

我不明白你說什麼,你可以幫助如何克服這個問題。 – biji

+0

我不知道如何讓它更清晰。你不明白什麼? –

+0

我現在消除了我的問題,現在我正在生成一個標籤名稱下的新XML文件,我正在存儲所有XML文件。我修改了我的腳本看看我的新腳本,但在這裏我還有一個問題可以幫助你請。 – biji

2

您可以切換到XML::Twig嗎?它提供了處理標籤的絕佳方式。

也許你需要像

my $twig=XML::Twig->new( 
    twig_handlers => 
     { 
     **student with specification** => sub { $_->delete;  }, # remove hidden elements 
     }, 

您需要使用規範修改學生爲你工作。對不起,我沒有太多時間,否則我會寫完整的代碼。

+0

我很新的一些建議,我通過XML走後到Perl語言同樣的問題::的libxml和我這樣寫的需要對我來說這麼多時間,每件事情都在起作用,你只知道問題。如果現在我想轉向XML :: Twig,那麼需要更多的時間,我需要修改整個代碼,請問如何解決這個問題。 – biji

0

下面是一些代碼,做它使用DOM文檔()

總體而言, 1)創建一個字符串或類似 2)負載的每個文件,導入父文檔,並追加 3)保存結果。

在XML編程中,使用XML解析器函數而不是字符串操作通常更好。

祝你好運。

function loadXMLString($strXML) { 
    $xmlDoc = new DOMDocument(); 
    $xmlDoc->formatOutput = true; 
    $xmlDoc->loadXML($strXML); 
    return $xmlDoc; 
} 

function loadXMLFile($strFileName, $defaultXML=null) { 
    $xmlDoc = new DOMDocument(); 
    if(file_exists($strFileName) ){ 
     $xmlDoc->load($strFileName); 
    } else { 
     if($defaultXML == null ) { 
      throw new Exception("Cannot locate file: " . $strFileName . " no default specified."); 
     } else { 
      // create it, if default XML is supplied 
      return $this->loadXMLString($defaultXML); 
     } 
    } 
    return $xmlDoc; 
} 


$xmlMain = loadXMLString("<xmlparent/>"); 

$xmlChild = loadXMLFile("test1.xml"); 
$ndTemp = $xmlMain->importNode($xmlChild->documentElement, true); 
$xmlMain->documentElement->appendChild($ndTemp); 

$xmlChild = loadXMLFile("test2.xml"); 
$ndTemp = $xmlMain->importNode($xmlChild->documentElement, true); 
$xmlMain->documentElement->appendChild($ndTemp); 

$xmlMain->save("all.xml"); 
+0

你使用了哪個模塊,我無法正確理解你的概念,你可以給出一些更詳細的解釋。如果我有幾個XML文件,我也需要這樣寫,否則我需要迭代任何循環。 – biji

+0

我使用PHP DOMDocument類,請參閱http://php.net/manual/en/class.domdocument.php –

+0

您也可以在循環中使用它。首先,加載$ xmlMain,然後在文件夾中啓動循環,爲每個文件加載一個新的$ xmlChild,並追加到$ xmlMain。最後,在循環完成後,保存$ xmlMain –