Perl code for Find and replace a tag value in XML

≡放荡痞女 提交于 2019-12-01 05:35:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!