If using XML::LibXML
, explicitly write the revised contents to disk:
# save
open my $out, '>', 'out.xml';
binmode $out; # as above
$doc->toFH($out);
# or
print {$out} $doc->toString();
题
I have a large xml of which I want to replace one of the attributes of node. I have a code which replaces the value of the attribute for the given node but it does not write to disk. I am not sure how should I make those changes propagated to disk?
For e.g: example.1.xml
<chairman name="abc" >
<vicechairman name="def">
<employee name="ghi" salary="123" designation="xyz"/>
</vicechairman>
</chairman>
In above example, I would like to change the value of employee nodes with "salary="123"" attribute to "salary="456"" such that above xml changes to:
<chairman name="abc" >
<vicechairman name="def">
<employee name="ghi" salary="456" designation="xyz"/>
</vicechairman>
</chairman>
I have following piece of code which after getting to node of "employee" changes the Attribute value to "salary=456", but does not write to disk:
foreach my $anode (@attributes){
my $attr = $anode->nodeName;
if($attr eq "salary"){
$anode->setValue( "456" );
}
}
Any help will be Appreciated. Thanks
解决方案
If using XML::LibXML
, explicitly write the revised contents to disk:
# save
open my $out, '>', 'out.xml';
binmode $out; # as above
$doc->toFH($out);
# or
print {$out} $doc->toString();
其他提示
With 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');
This updates the file inplace.If you don't want to update inplace, use ->print_to_file( 'out.xml')
This will work without using much memory, as only the nodes that trigger the handler are loaded in memory (and removed once used, so you only have a single one in memory at any given time).