问题
Below is the XML I will be using:
<a>
<id>ABC</id>
<class />
<gender />
</a>
I want to write a Perl code which search for tag 'id' and replace the value "ABC" with "DEF".
However the nesting of above XML can change. So I want to make a generalized code that search for the tag 'id' independently of its exact position.
Till now i am able to get the logic where i can replace the value in ABC but that makes my code static of the position of tag 'id'.
#!usr/bin/perl
use warnings;
use XML::Simple;
use Spreadsheet::ParseExcel;
use Data::Dumper;
my $FileName = 'sample.xls';
my $xml_file = 'hello.xml';
$par=$ARGV[0];
my $xml = XMLin($xml_file,
KeepRoot=>1,
ForceArray=>1,);
$xml->{a}->[0]->{id}='DEF';
XMLout(
$xml,
KeepRoot =>1 ,
NoAttr =>1,
OutputFile => $xml_file,
);
}
回答1:
XPath is able to find nodes without needing to know the position in the tree.
use strictures;
use XML::LibXML qw();
my $dom = XML::LibXML->load_xml(string => <<'XML');
<a>
<id>ABC</id>
<class />
<gender />
</a>
XML
for my $id ($dom->findnodes('//id[string()="ABC"]')) {
$id->removeChildNodes;
$id->appendText('DEF');
}
print $dom->toString
回答2:
A simple XML::Twig solution would be:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $FILE= 'id.xml';
XML::Twig->new( twig_handlers => { 'id[string()="ABC"]' => sub { $_->set_text( 'DEF'); } },
keep_spaces => 1,
)
->parsefile( $FILE)
->print_to_file( $FILE);
Just for fun: an efficient XML::Twig solution is a bit more convoluted, mostly because you can't use string()
conditions with twig_roots
. Still, it's quite compact, and it never loads the whole file in memory.
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
XML::Twig->new( twig_roots => { id => sub { $_->flush }, },
twig_handlers => { 'id[string()="ABC"]' => sub { $_->set_text( 'DEF'); } },
twig_print_outside_roots => 1,
)
->parsefile_inplace( 'id.xml');
回答3:
perl -i.bak -pe 's/abc/def/g' myfile.xml
you'll get a new file myfile.xml.bak which ha
来源:https://stackoverflow.com/questions/11482365/perl-code-for-find-and-replace-a-tag-value-in-xml