tags:

views:

122

answers:

2

Hi! Why do I get my string two times in the output?

#!/usr/bin/perl
use warnings;
use strict;

use XML::Twig;


my $string = '<cd_catalogue><title>Hello, World!</title></cd_catalogue>';

my $t= XML::Twig->new(  twig_handlers    => { cd_catalogue => \&cd_catalogue, },
            pretty_print => 'indented', 
);

$t->parse( $string );


sub cd_catalogue {
    my( $t, $cd_catalogue ) = @_;
    $cd_catalogue->flush;
}


# Output:
#<cd_catalogue>
#  <title>Hello, World!</title>
#</cd_catalogue>
#<cd_catalogue>
#  <title>Hello, World!</title>
#</cd_catalogue>
+2  A: 

Changing your sub to use print and purge instead of flush gets around problem:

sub cd_catalogue {
    my( $t, $cd_catalogue ) = @_;
    $cd_catalogue->print;
    $cd_catalogue->purge;
}

The flush is getting confused because of the simplicity of your example because cd_catalogue is root node. If you change your data to something like this:

my $string = '
    <cds>
        <cd_catalogue><title>Hello, World!</title></cd_catalogue>
    </cds>';

or if you changed your twig_handler to look for title:

twig_handlers    => { title => \&cd_catalogue }

then you will find that $cd_catalogue->flush now works as expected with your $string.

/I3az/

draegtun
+2  A: 

Your program uses XML::Twig incorrectly. According to the documentation, you should "always flush the twig, not an element."

Change cd_catalogue to

sub cd_catalogue {
    my( $t, $cd_catalogue ) = @_;
    $t->flush;
}

to get the expected behavior.

Greg Bacon
Strangely this is what I put originally in my answer :) However the documentation does say and also provides examples of using flush with "elements" (http://search.cpan.org/dist/XML-Twig/Twig.pm#Processing_an_XML_document_chunk_by_chunk).
draegtun
yes, flushing on an element flushes up to that element, I will fix the docs. Thanks
mirod