in reply to Re: (jeffa) Re: XML Search and Replace
in thread XML Search and Replace

Had to run to lunch ... here is another version that DWYW ;)
use strict; use XML::Parser; use XML::Writer; my $writer = XML::Writer->new(); my $parser = XML::Parser->new( Handlers => { Init => \&handle_Init, Start => \&handle_Start, Char => \&handle_Char, End => \&handle_End, Final => \&handle_Final, } ); my $data = do {local $/;<DATA>}; $parser->{match} = 'opponent'; $parser->parse($data); sub handle_Init { $writer->xmlDecl('UTF-8'); $writer->doctype('xml'); } sub handle_Start { my($self,$name,%atts) = @_; $self->{flag} = 1 if $name eq $self->{match}; $writer->startTag($name,%atts); } sub handle_Char { my($self,$text) = @_; if ($self->{flag}) { if ($text eq 'Terrance Rattigan') { $text = 'breakfast'; } else { $text =~ s/goose/Queen Elizabeth/; } delete $self->{flag}; } $writer->characters($text); } sub handle_End { my($self,$name) = @_; $writer->endTag($name); } sub handle_Final { $writer->end(); } __DATA__ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xml> <xml> <struggle class="life or death"> <opponent>wolf</opponent> <opponent>ant</opponent> </struggle> <struggle class="life or death"> <opponent>pantomime goose</opponent> <opponent>Terrance Rattigan</opponent> </struggle> </xml>
If a start element named 'opponent' is found, we set a flag - why not use the parser's namespace? ;) Next, each time a non-markup character is encountered, we see if the flag is set and if it is, do some conversions and erase the flag.

Most of my XML munging (until recently) has been with XML::Simple. That module builds an internal tree that represents the document. As Dog and Pony showed you, it is a really easy module to work with, but as the document you are munging gets larger, XML::Simple gets slower and takes up more memory.

These two versions i supplied use XML::Parser to take advantage of 'event streams', they are more economical in speed and memory. But they are also more complicated, as you can immediately tell by comparing my code with Dog and Pony's.

jeffa

"Here we see a life and death stuggle between jeffa and Dog and Pony ..." ;)