替换XML内容并写入磁盘

时间:2014-04-29 22:19:58

标签: xml perl libxml2

我有一个大的xml,我想替换node的一个属性。我有一个代码替换给定节点的属性值但它不写入磁盘。我不确定如何将这些更改传播到磁盘?

例如:example.1.xml

<chairman name="abc" >
<vicechairman name="def">
<employee name="ghi" salary="123" designation="xyz"/>
</vicechairman>
</chairman>

在上面的示例中,我想用&#34; salary =&#34; 123&#34;&#34;更改员工节点的值。属于&#34;薪水=&#34; 456&#34;&#34;以上xml更改为:

<chairman name="abc" >
<vicechairman name="def">
<employee name="ghi" salary="456" designation="xyz"/>
</vicechairman>
</chairman>

我到了&#34; employee&#34;的节点后面有一段代码。将属性值更改为&#34; salary = 456&#34;,但不写入磁盘:

foreach my $anode (@attributes){
    my $attr = $anode->nodeName;
    if($attr eq "salary"){
        $anode->setValue( "456" );
    }
}

任何帮助都会得到赞赏。谢谢

2 个答案:

答案 0 :(得分:1)

如果使用XML::LibXML,请将修改后的内容明确写入磁盘:

# save
open my $out, '>', 'out.xml';
binmode $out; # as above
$doc->toFH($out);
# or
print {$out} $doc->toString();

答案 1 :(得分:0)

使用XML :: Twig:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $old_sal="123";
my $new_sal="456";

XML::Twig->new( twig_roots => { qq{employee[\@salary="$old_sal"]} 
                                  => sub { $_->set_att( salary => $new_sal); $_->flush; } 
                              },
                twig_print_outside_roots => 1,
              )
         ->parsefile_inplace( 'emp.xml');

这会在原地更新文件。如果您不想在原地更新,请使用->print_to_file( 'out.xml')

这可以在不占用太多内存的情况下工作,因为只有触发处理程序的节点才会加载到内存中(并且一旦使用就删除,因此在任何给定时间内只有一个内存中的一个)。