Nate Glenn
Nate Glenn

Reputation: 6744

XML::Twig changes erased

The program below gives me weird output that I cannot explain:

use strict;
use warnings;
use XML::Twig;

my $xml = 
q{<block>
    <foo>bar baz</foo>
</block>};

my $twig = XML::Twig->new(
        TwigHandlers => {foo => \&foo, block => \&block},
    );

print "after parse: " . $twig->parse($xml)->sprint;


sub foo {
    my ( $twig, $foo ) = @_;

    my $text = $foo->sprint("don't print outside element");
    my $newSummary = XML::Twig::Elt->parse( '<p><i>' . $text . '</i></p>' );
    $newSummary->paste( 'before', $foo);
    my $parent = $foo->parent;
    # $foo->delete;
    print "foo: " . $parent->sprint . "\n\n";
}

sub block {
    my ($twig, $block) = @_;
    print "block: " . $block->sprint . "\n\n";
}

It prints the following:

foo: <block><p><i>bar baz</i></p><foo>bar baz</foo></block>

block: <block><p><i>bar baz</i></p><foo>bar baz</foo></block>

after parse: <block><foo>bar baz</foo></block>

So I am modifying the twig inside of the foo handler, the change is sticking around for the block handler to see it, but then when processing is all done, the change goes away. What is going on here? How can I make my change stick for the lifetime of the twig?

Upvotes: 2

Views: 135

Answers (1)

mirod
mirod

Reputation: 16171

It looks like a bug, or at least a problem with scoping: the new element seems to be garbage collected when the parse finishes.

One way to avoid this is to add a copy to the creation of the element:

my $newSummary = XML::Twig::Elt->parse( '<p><i>' . $text . '</i></p>' )->copy;

Upvotes: 4

Related Questions