2013-02-22 47 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