Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

XML::Generator::PerlData and attributes

by dda (Friar)
on Oct 14, 2003 at 11:41 UTC ( #299079=perlquestion: print w/replies, xml ) Need Help??
dda has asked for the wisdom of the Perl Monks concerning the following question:

Hello all.

I'm trying to use XML::Generator::PerlData module, and I can't generate attribute=value pair:

#!/usr/bin/perl -w use strict; use XML::Generator::PerlData; use XML::Handler::YAWriter; use IO::File; my $handler = XML::Handler::YAWriter->new( Output => new IO::File (">-"), Pretty => { PrettyWhiteIndent => 1, PrettyWhiteNewline => 1, CompactAttrIndent => 1 }); my $pd = XML::Generator::PerlData->new(Handler => $handler); $pd->attrmap(entry => ['attr2']); $pd->parse_start(); $pd->start_tag('entry', attr1 => 'value1'); my $href; $href->{path} = 'path'; $href->{attr2} = 'value2'; $pd->parse_chunk($href); $pd->end_tag('entry'); $pd->parse_end(); _OUTPUT_ <?xml version="1.0" encoding="UTF-8"?> <document> <entry {}attr1="HASH(0x1f0bb00)"> <path>path </path> </entry> </document>
As you see, attribute and value passed to start_tag generate {}attr1="HASH(0x1f0bb00)", and the call to $pd->attrmap(entry => ['attr2']), supposed to add attr2="value2"pair inside entryelement just hides attr2 at all.

What's wrong with it? Please help me.


Replies are listed 'Best First'.
Re: XML::Generator::PerlData and attributes
by jeffa (Bishop) on Oct 14, 2003 at 13:07 UTC
    Well, i have been trying to get this to work for 30 minutes now with no luck. I even pulled in one the test files from the distro and it didn't "work": There could be a bug in this version (0.89) or we could both be missing how to properly use this module. My suggestion is to (well, always explain what you are trying to accomplish first!) pick another module. From the docs, it appears that this one may have been designed to be used with a database. If that is the case, then try XML::Generator::DBI instead. I wrote a tutorial on it over at XML::Generator::DBI Tutorial. Best of luck. :)


    (the triplet paradiddle with high-hat)
      Thanks jeffa. I'm not using DBI -- what I'm trying to do is to make XML document from LDAP tree. I'm getting an ugle XML code without attibutes. :)

      Does it worth to email to the author of this module?


        I would wait at least a day before emailing the author - maybe someone here at the Monastery will figure it out. If and when you do email the author, be very consise and polite (you know this ;)). Matts has written many XML modules and perhaps he has used this one before, you might want to /msg him and invite him to look at your question. mirod is another XML Wizard, he may have an alternative for you.

        Another outlet is - if this is a bug, you can report it to the author at


        (the triplet paradiddle with high-hat)
Re: XML::Generator::PerlData and attributes
by Matts (Deacon) on Oct 19, 2003 at 12:53 UTC
    The output from XML::Generator::PerlData is SAX2, not SAX1, so you have to either run it through XML::Filter::SAX2toSAX1 before output to XML::Handler::YAWriter, or use XML::SAX::Writer to output it.
Re: XML::Generator::PerlData and attributes
by mirod (Canon) on Oct 15, 2003 at 10:44 UTC

    It looks like there is a problem with the module, either with the code or with the docs. For such problems with uncommon XML modules you should try asking on the perl-xml mailing list (Kip usually reads it). If you don't get an answer you can then try contacting the author and/or reporting the bug through

    In this case I would probably use a different module though. See below for a bunch of possibilities (there are many more, from XML::LibXML to XML::SAX::Writer):

    #!/usr/bin/perl -w use strict; use Test::More qw(no_plan); use XML::SemanticDiff; use File::Slurp; use Getopt::Std; my %opt; # -v is verbose, it displays the generated string for each test getopts( 'v', \%opt); # XML::SemanticDiff seems to only compare files, not strings my $tmp_expected= "tmp.expected"; # temp file with expected result my $tmp_result = "tmp.result"; # temp file with result my %tests=( 'XML::Simple' => { sub => \&test_xml_simple, }, 'XML::Writer' => { extra_modules => [ 'IO::Scalar' ], sub => \&test_xml_writer, }, 'XML::Handler::YAWriter' => { sub => \&test_xml_handler_yawriter, + }, 'XML::Twig' => { sub => \&test_xml_twig, }, ); write_file( $tmp_expected, <DATA>); my $sem_diff= XML::SemanticDiff->new; foreach my $module ( keys %tests) { my $test= $tests{$module}; my @modules= ($module); push @modules, @{$test->{extra_modules}} if( $test->{extra_modules +}); if( load_modules( @modules)) { my $result= $test->{sub}->(); write_file( $tmp_result, $result); my $diff= $sem_diff->compare( $tmp_expected, $tmp_result); ok( ! $diff, $module) or diag( "got $result") ; diag( "\n", $result, "\n\n") if( $opt{v}); } else { SKIP: { skip( "$module not available", 1); } } } unlink $tmp_expected, $tmp_result; sub test_xml_simple { my $xml= { entry => { att1 => 'value1', att2 => 'value2', path => +{ content => 'path & text'} } }; return XMLout( $xml, keeproot => 1); } sub test_xml_writer { my $result; my $output = IO::Scalar->new( \$result); my $writer = XML::Writer->new(OUTPUT => $output); $writer->startTag( entry => att1 => 'value1', att2 => 'value2'); $writer->dataElement( path => 'path & text'); $writer->endTag( 'entry'); $writer->end(); $output->close(); return $result; } sub test_xml_handler_yawriter { my $writer= XML::Handler::YAWriter->new( AsString => 1); $writer->start_document; $writer->start_element( { Name => 'entry', Attributes => { att1 => + 'value1', att2 => 'value2'} } ); $writer->start_element( { Name => 'path' } ); $writer->characters( { Data => 'path & text' } ); $writer->end_element( { Name => 'path'} ); $writer->end_element( { Name => 'entry'} ); return $writer->end_document; } sub test_xml_twig { my $root= XML::Twig::Elt->new( entry => { att1 => 'value1', att2 = +> 'value2' }); $root->insert_new_elt( path => "path & text"); return $root->sprint; } # a simple way of importing modules at run time #sub load_modules # { foreach (@_) # { if(eval "require $_") { import $_; } # else { return 0; } # } # return 1; # } # fun way sub load_modules { ((eval "require $_" and import $_ or 1) or return 0) foreach (@_) +; 1} __DATA__ <entry att1="value1" att2="value2"> <!-- the &amp; is here to test escaping --> <path>path &amp; text</path> </entry>

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://299079]
Approved by valdez
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2017-07-21 16:17 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (329 votes). Check out past polls.