3

输入 XML

<?xml version="1.0" encoding="utf-8"?>
<!--00/00/0000 12:35:25 AM-->
<Physical xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
  <Pro managementID="22000020">
    <Identification Type="XXXXX" >          
      <Address>
        <Data>test</Data>        
      </Address>
      <Phone>
        <Number>0000</Number>
      </Phone>
      <Email>test@com</Email>
    </Identification>       
  </Pro>
</Physical>

脚本:

我正在尝试更改标签的值并将其余部分打印到新的输出 xml 文件中

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;     

  my $xml = XML::Simple->new(ForceContent => 1,);
  my $xmlData = $xml->XMLin('input.xml') or die$!;     

  print Dumper (\$xmlData);

  foreach my $xmlKey ( keys %{$xmlData} ){
   if ( $xmlKey =~ m/Pro/){
       print ${$xmlData}{$xmlKey}{Identification}{Address}{Data}="hello";
    }
  }

XMLout(
    $xmlData,
    KeepRoot => 1,
    NoAttr => 0,
    OutputFile => $xml_out,
);

输出 XML:

<opt xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Pro managementID="22000020">
     <Identification Type="XXXXX">
      <Address Data="hello" />
      <Email>test@com</Email>
      <Phone name="Number">0000</Phone>
    </Identification>
  </Pro>
</opt>

我可以更改值,但是当我尝试将数据写入输出时,格式已更改。任何人都可以指导我获取具有更改值的相同输入数据作为输出。

4

5 回答 5

4

以这种方式使用 XML::LibXML:

#!/usr/bin/perl
use strict;
use warnings;

use XML::LibXML;

my $input;
while(<>) {
    $input .= $_;
}
my $xml_doc = XML::LibXML->load_xml(string => $input);
my $xpath_ctx = new XML::LibXML::XPathContext($xml_doc);
$xpath_ctx->find("/Physical/Pro/Identification/Address/Data")->get_node(0)->firstChild()->setData("hello");
my $xml_data = $xpath_ctx->find("/")->get_node(0)->toString(1);

print $xml_data;

XML::LibXML 速度更快,并且在 XPath 的帮助下,操作$xml_doc更容易。

您可以在这里找到更多信息

于 2012-10-29T09:40:41.640 回答
2

一个 XML::Twig 版本:

#!/usr/bin/perl 

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_roots => { 'Pro/Identification/Address/Data' => sub { $_->set_text( 'hello'); $_->flush; } },
                twig_print_outside_roots => 1,
              )
         ->parsefile( 'input.xml');
于 2012-10-29T11:27:56.797 回答
2

使用不同的 XML 处理模块。例如,此脚本使用XML::XSH2,它是XML::LibXML的包装器:

#!/usr/bin/perl
use warnings;
use strict;

use XML::XSH2;

xsh << 'END';
    open input.xml ;
    for //*[xsh:matches(name(),'Pro')]/Identification/Address/Data
        set . 'hello' ;
    save :b ;
END
于 2012-10-29T09:34:31.633 回答
1

使用 XML::Rules 的另一种方式

use strict;
use warnings;

use XML::Rules;

my @rules = (
  Data => sub { $_[1]{_content} =~ s/test/hello/; return $_[0] => $_[1] },
);
my $xr = XML::Rules->new(
  rules => \@rules,
  style => 'filter',
);

$xr->filterfile('input.xml');
于 2012-10-29T17:43:58.130 回答
0

您已将NoAttr输出设置为零。

这不是你想要的相反吗?

无属性 => 1

当与 XMLout() 一起使用时,生成的 XML 将不包含任何属性。所有哈希键/值都将表示为嵌套元素。

NoAttr 将停止

<Phone>
    <Number>0000</Number>

转变为

 <Phone name="Number">
于 2012-10-30T00:46:28.913 回答