Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: XML::Twig 'cut' and 'paste' Question

by Ieronim (Friar)
on Jul 28, 2006 at 19:30 UTC ( [id://564437]=note: print w/replies, xml ) Need Help??


in reply to XML::Twig 'cut' and 'paste' Question

You modify the document with every cut'n'paste—the <label> are direct children of the <fig> element the first time, but then the first label becomes a grandchild of <fig>! Of course, you get the error Can't call method "cut" on an undefined value when you try to get the $c'th element from the list containing only one label.

This error appeared because you chose an extremely ineffective way—you call get_xpath on every element in the list instead of fetching all elements once.

The corected variant of your code:

#!/usr/bin/perl use warnings; use strict; use XML::Twig; my $twig = new XML::Twig( pretty_print => 'indented', ); $twig->parse(<<'XML'); <?xml version="1.0"?> <article> <label>here label for testing</label> <fig id="fig001" position="float"><label>Fig. 1.</label><caption><p>fi +rst</p></caption></fig> <fig id="fig002" position="float"><label>Fig. 2.</label><caption><p>se +cond</p></caption></fig> <fig id="fig003" position="float"><label>Fig. 3.</label><caption><p>th +ird</p></caption></fig> <fig id="fig004" position="float"><label>Fig. 4.</label><caption><p>fo +urth</p></caption></fig> <fig id="fig005" position="float"><label>Fig. 5.</label><caption><p>fi +fth</p></caption></fig> <fig id="fig006" position="float"><label>Fig. 6.</label><caption><p>si +xth</p></caption></fig> </article> XML my $count = $twig->get_xpath('/article/fig//label'); for my $c (0..($count-1)) { my $t = $twig->get_xpath('/article/fig/label', 0); #//f +ig/label -here problem comes my $pl = $twig->get_xpath('/article/fig//caption', $c); my $cut = $t->cut ; $cut->paste('first_child', $pl) ; + } $twig->print;

The more efficient and clean way resulting in the same output:

#!/usr/bin/perl use warnings; use strict; use XML::Twig; my $twig = new XML::Twig( pretty_print => 'indented', ); $twig->parse(<<'XML'); <?xml version="1.0"?> <article> <label>here label for testing</label> <fig id="fig001" position="float"><label>Fig. 1.</label><caption><p>fi +rst</p></caption></fig> <fig id="fig002" position="float"><label>Fig. 2.</label><caption><p>se +cond</p></caption></fig> <fig id="fig003" position="float"><label>Fig. 3.</label><caption><p>th +ird</p></caption></fig> <fig id="fig004" position="float"><label>Fig. 4.</label><caption><p>fo +urth</p></caption></fig> <fig id="fig005" position="float"><label>Fig. 5.</label><caption><p>fi +fth</p></caption></fig> <fig id="fig006" position="float"><label>Fig. 6.</label><caption><p>si +xth</p></caption></fig> </article> XML my @labels = $twig->get_xpath('/article/fig/label'); my @captions = $twig->get_xpath('/article/fig/caption'); for my $i (0..$#labels) { $labels[$i]->move('first_child', $captions[$i]); } $twig->print;
But i myself would prefer to let twig_handlers do the job:
#!/usr/bin/perl use warnings; use strict; use XML::Twig; my $twig = new XML::Twig( twig_handlers => { '/article/fig' => sub { my $label = $_->first_child('label') or return; my $caption = $_->first_child('caption') or return; $label->move('first_child', $caption); $_->flush; } }, pretty_print => 'indented', ); $twig->parse(<<'XML'); <?xml version="1.0"?> <article> <label>here label for testing</label> <fig id="fig001" position="float"><label>Fig. 1.</label><caption><p>fi +rst</p></caption></fig> <fig id="fig002" position="float"><label>Fig. 2.</label><caption><p>se +cond</p></caption></fig> <fig id="fig003" position="float"><label>Fig. 3.</label><caption><p>th +ird</p></caption></fig> <fig id="fig004" position="float"><label>Fig. 4.</label><caption><p>fo +urth</p></caption></fig> <fig id="fig005" position="float"><label>Fig. 5.</label><caption><p>fi +fth</p></caption></fig> <fig id="fig006" position="float"><label>Fig. 6.</label><caption><p>si +xth</p></caption></fig> </article> XML $twig->print;

     s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://564437]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-24 07:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found