0

我想将 WSMAN 给出的 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>

我无法解析上面的输出,因为上面的输出包含 2 个根元素,这些元素在XMLXML::Simple方面是“垃圾”

问题/陈述:

我想将以上输出分成两个不同的 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行和更多行写入这个新文件,直到再次遇到?xml version模式。

3)每次遇到?xml version模式时都按照步骤2

这是我的代码:

#!/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>

你能帮我修复我的脚本以创建两个不同的 XML 文件吗?

4

1 回答 1

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 $_;
}
于 2013-02-22T10:58:41.417 回答