2013-02-22 82 views
0

我想將WSMAN給出的XML輸出分解爲多個XML文件,以便我可以解析輸出。將XML文件分解成多個XML文件

WSMAN給我輸出如下面基本上具有與每個具有其自己的根節點兩個不同的XML文件:

<?xml version="1.0" encoding="UTF-8"?> 
    <s:Body> 
    <wsen:PullResponse> 
     <wsen:Items> 
     <n1:DCIM_SoftwareIdentity> 
      <n1:ComponentType>BIOS</n1:ComponentType> 
      <n1:InstanceID>DCIM:CURRENT#741__BIOS.Setup.1-1</n1:InstanceID> 
      <n1:VersionString>1.3.6</n1:VersionString> 
     </n1:DCIM_SoftwareIdentity> 
     </wsen:Items> 
    </wsen:PullResponse> 
    </s:Body> 
<?xml version="1.0" encoding="UTF-8"?> 
    <s:Body> 
    <wsen:PullResponse> 
     <wsen:Items> 
     <n1:DCIM_SoftwareIdentity> 
      <n1:ComponentType>BIOS</n1:ComponentType> 
      <n1:InstanceID>DCIM:INSTALLED#741__BIOS.Setup.1-1</n1:InstanceID> 
      <n1:VersionString>1.3.6</n1:VersionString> 
     </n1:DCIM_SoftwareIdentity> 
     </wsen:Items> 
    </wsen:PullResponse> 
    </s:Body> 

我不能XML::Simple解析上述輸出如上述輸出包含2個元件,其是「垃圾「在XML

問題/聲明方面:

我想突破輸出與各containi兩個不同的XML文件如下面納克它自己的根元素:

<?xml version="1.0" encoding="UTF-8"?> 
    <s:Body> 
    <wsen:PullResponse> 
     <wsen:Items> 
     <n1:DCIM_SoftwareIdentity> 
      <n1:ComponentType>BIOS</n1:ComponentType> 
      <n1:InstanceID>DCIM:CURRENT#741__BIOS.Setup.1-1</n1:InstanceID> 
      <n1:VersionString>1.3.6</n1:VersionString> 
     </n1:DCIM_SoftwareIdentity> 
     </wsen:Items> 
    </wsen:PullResponse> 
    </s:Body> 

......

<?xml version="1.0" encoding="UTF-8"?> 
    <s:Body> 
    <wsen:PullResponse> 
     <wsen:Items> 
     <n1:DCIM_SoftwareIdentity> 
      <n1:ComponentType>BIOS</n1:ComponentType> 
      <n1:InstanceID>DCIM:INSTALLED#741__BIOS.Setup.1-1</n1:InstanceID> 
      <n1:VersionString>1.3.6</n1:VersionString> 
     </n1:DCIM_SoftwareIdentity> 
     </wsen:Items> 
    </wsen:PullResponse> 
    </s:Body> 

我的邏輯:

1)解析由線的輸出線

2 )如果遇到?xml version模式,則創建一個新的XML文件並將?xml version行和其他行寫入此新文件,直到agai你遇到?xml version模式。

3)按照步驟2每次遇到一次?xml version模式

這裏是我的代碼:

#!/usr/bin/perl -w 
use strict; 
use XML::Simple; 
use Data::Dumper; 

my $counter = 0; 
my $fileName; 

while (my $line = <DATA>) 
{ 
    if ($line =~ /\?xml version/) 
    { 
     $counter++; 
     print "Creating the BIOS file \n"; 
     $fileName = "BIOS"."_".$counter; 
    } 
    open (my $sub_xml_file, ">" , $fileName) or die "Canot create $fileName: $!\n"; 
    print $sub_xml_file $line; 
} 

__DATA__ 
## omitting this part as this contains the XML info listed above. 

現在,我的腳本將創建一個文件BIOS_1BIOS_2但只寫的最後一行以上XML輸出到它:

# cat BIOS_1 
    </s:Body> 
# cat BIOS_2 
    </s:Body> 

你能幫我修復我的腳本,以創建兩個區別ct XML文件...

+1

您正在打開(和截斷)輸出文件輸入的每一行。聲明'my $ sub_xml_file;'在while循環之外,並在if塊中打開($ sub_xml_file,...)。 – runrig 2013-02-22 15:49:32

+0

+ 1,@ runrig,您的解釋很有幫助。謝謝。 – slayedbylucifer 2013-02-22 16:08:04

回答

0

永遠不會保留$line用於將來的循環傳遞。

負載一切記憶方法:每次方式

my $count; 
my $file; { local $/; $file = <>; } 
for my $xml (split /^(?=<\?xml)/m, $file) { 
    my $fn = sprintf("BIOS_%d.xml", ++$count); 
    open(my $fh, '>', $fn) or die $!; 
    print $fh $xml; 
} 

線:

my $fh; 
my $count; 
while (<>) { 
    if (/^<\?xml/) { 
     my $fn = sprintf("BIOS_%d.xml", ++$count); 
     open($fh, '>', $fn) or die $!; 
    } 

    print $fh $_; 
} 
+0

謝謝。我正在使用「一次一行」的方法,它正在工作。你能幫我解決我的代碼嗎?我不明白你的意思是「你永遠不會保留$行」 – slayedbylucifer 2013-02-22 11:08:10

+0

你讀的行,你不保存它們。所以當你來印刷時他們不可用。 – ikegami 2013-02-22 11:25:21