jxh has asked for the wisdom of the Perl Monks concerning the following question:

Consider :
#!/usr/bin/perl -w use strict; use XML::Twig; my $twig; my $xml; $twig=XML::Twig->new( pretty_print => 'record_c', NoLWP => 1, keep_spaces => 1, load_DTD => 1, expand_external_ents => 1, keep_encoding => 1, ); { local $/; $xml = <DATA>; } $twig->parse("$xml"); $twig->print __DATA__ <?xml version="1.0"?> <!DOCTYPE garden SYSTEM "./garden.dtd"> <garden> <plant>&flower;</plant> </garden>
My external dtd, garden.dtd looks like this :
<!ENTITY flower "%flower_ref;"> <!ENTITY % flower_ref "daffodil">
When I run my code, I get : illegal parameter entity reference at line 2, column 17, byte 36 at /usr/local/lib/perl5/site_perl/5.6.1/sun4-solaris/XML/Parser.pm line 185
Why is this ?
I am looking to have all referaances resolved when printing...
Many Thanks.

Replies are listed 'Best First'.
Re: XML::Twig - resolving parameter entity decalarations
by mirod (Canon) on May 03, 2006 at 17:07 UTC

    The XML might not well-formed.

    I can't tell you why off the top of my head, I haven't used parameter entities in a while, but if you put the xml in a separate file and if you run xmllint (the XML checker that comes with libxml2) it complains that the entity flower is not defined.

    That said, when I add the proper element declarations and when I reverse the order of the 2 entity declarations, xmllint is quite happy, so it looks indeed like XML::Twig does not deal properly with parameter entities, I have to check, I haven't touched that corner of the code in years.

    Actually, after looking a little deeper, it looks like it's an XML::Parser problem: when loading the external DTD, XML::Twig parses a fake document that's just the DTD and a dummy element, in order to get the entity values, otherwise XML::Parser does not read the external DTD at all.

    But when I parse the document created from the DTD, either with XML::Parser or just with xmlwf (the xml checker that comes with expat), I get an "illegal parameter entity reference" error.

    The document is:

    <!DOCTYPE dummy [ <!ENTITY % flower_ref "daffodil"> <!ENTITY flower "%flower_ref;"> ]> <dummy/>

    So this looks a bit tricky to fix. If you have any idea, I'll take it ;--(