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

Update:
This behavior is correct as per the source code.
(Sure wish there was an explanatory blurb explaining that XML::Twig::Elt->new() removes the '#CDATA' key in an attribute hashref. C'est la vie.)

Thank you haukex and Anon Monk for your explanation and workarounds!


Good afternoon!

I am experiencing a rather unexpected issue creating new elements with XML::Twig's XML::Twig::Elt->new() method where the '#CDATA' key in my attribute hashref gets undefined after passing it to new().

e.g.:

my $attributes = $sibling_element->atts(); $attributes->{'#CDATA'} = 1; # '#CDATA' attribute is defined here my $elt1 = XML::Twig::Elt->new('present', $attributes, 'This is in CDA +TA'); # '#CDATA' attribute is undefined here my $elt2 = XML::Twig::Elt->new('missing', $attributes, 'This is not in + CDATA');

Is this supposed to happen? I did not see anything mentioning this in the CPAN docs...

Thank you for your time.

Perl info:

perl -v This is perl 5, version 26, subversion 0 (v5.26.0) built for MSWin32-x +64-multi-thread
XML::Twig info: 3.52

Sample code:
#!/usr/bin/perl use 5.026; use strict; use warnings; use XML::Twig; { open (my $OFILE, '>:utf8', 'file.out.xml') or die "$!\n$^E"; my $t = XML::Twig->new( twig_handlers => { '/keys/key' => sub { makeDuplicates(@_, $OFILE); 1; }, }, output_encoding => 'utf-8', pretty_print => 'indented', ); $t->safe_parse(\*DATA); if ( $@ ) { die "Error occured in XML data\n$@"; } close $OFILE; } sub makeDuplicates { my ($_twig, $key_element, $OFILE) = @_; my $text = $key_element->text(); my $attributes = $key_element->atts(); $attributes->{'#CDATA'} = 1; # '#CDATA' attribute is defined here my $lc_element = XML::Twig::Elt->new('lc_key', $attributes, lc $text +); # '#CDATA' attribute is undefined here my $uc_element = XML::Twig::Elt->new('uc_key', $attributes, uc $text +); $lc_element->paste(after => $key_element); $uc_element->paste(after => $key_element); $_twig->flush($OFILE); return; } __DATA__ <?xml version="1.0" encoding="utf-8"?> <keys> <key order='01'><![CDATA[One hen]]></key> <key order='02'><![CDATA[Two ducks]]></key> <key order='03'><![CDATA[Three squawking geese]]></key> <key order='04'><![CDATA[Four limerick oysters]]></key> <key order='05'><![CDATA[Five corpulent porpoises]]></key> <key order='06'><![CDATA[Six pair of Don Alverzo's tweezers]]></key> <key order='07'><![CDATA[Seven thousand Macedonians in full battle a +rray]]></key> <key order='08'><![CDATA[Eight brass monkeys from the ancient sacred + crypts of Egypt]]></key> <key order='09'><![CDATA[Nine apathetic, sympathetic, diabetic old m +en on roller skates, with a marked propensity towards procrastination + and sloth]]></key> <key order='10'><![CDATA[Ten lyrical, spherical, diabolical denizens + of the deep who stalk about the corners of the cove all at the same +time.]]></key> </keys>

Desired output:

<?xml version="1.0" encoding="utf-8"?> <keys> <key order="01"><![CDATA[One hen]]></key> <uc_key order="01"><![CDATA[ONE HEN]]></uc_key> <lc_key order="01"><![CDATA[one hen]]></lc_key> <key order="02"><![CDATA[Two ducks]]></key> <uc_key order="02"><![CDATA[TWO DUCKS]]></uc_key> <lc_key order="02"><![CDATA[two ducks]]></lc_key> <key order="03"><![CDATA[Three squawking geese]]></key> <uc_key order="03"><![CDATA[THREE SQUAWKING GEESE]]></uc_key> <lc_key order="03"><![CDATA[three squawking geese]]></lc_key> <key order="04"><![CDATA[Four limerick oysters]]></key> <uc_key order="04"><![CDATA[FOUR LIMERICK OYSTERS]]></uc_key> <lc_key order="04"><![CDATA[four limerick oysters]]></lc_key> <key order="05"><![CDATA[Five corpulent porpoises]]></key> <uc_key order="05"><![CDATA[FIVE CORPULENT PORPOISES]]></uc_key> <lc_key order="05"><![CDATA[five corpulent porpoises]]></lc_key> <key order="06"><![CDATA[Six pair of Don Alverzo's tweezers]]></key> <uc_key order="06"><![CDATA[SIX PAIR OF DON ALVERZO'S TWEEZERS]]></u +c_key> <lc_key order="06"><![CDATA[six pair of don alverzo's tweezers]]></l +c_key> <key order="07"><![CDATA[Seven thousand Macedonians in full battle a +rray]]></key> <uc_key order="07"><![CDATA[SEVEN THOUSAND MACEDONIANS IN FULL BATTL +E ARRAY]]></uc_key> <lc_key order="07"><![CDATA[seven thousand macedonians in full battl +e array]]></lc_key> <key order="08"><![CDATA[Eight brass monkeys from the ancient sacred + crypts of Egypt]]></key> <uc_key order="08"><![CDATA[EIGHT BRASS MONKEYS FROM THE ANCIENT SAC +RED CRYPTS OF EGYPT]]></uc_key> <lc_key order="08"><![CDATA[eight brass monkeys from the ancient sac +red crypts of egypt]]></lc_key> <key order="09"><![CDATA[Nine apathetic, sympathetic, diabetic old m +en on roller skates, with a marked propensity towards procrastination + and sloth]]></key> <uc_key order="09"><![CDATA[NINE APATHETIC, SYMPATHETIC, DIABETIC OL +D MEN ON ROLLER SKATES, WITH A MARKED PROPENSITY TOWARDS PROCRASTINAT +ION AND SLOTH]]></uc_key> <lc_key order="09"><![CDATA[nine apathetic, sympathetic, diabetic ol +d men on roller skates, with a marked propensity towards procrastinat +ion and sloth]]></lc_key> <key order="10"><![CDATA[Ten lyrical, spherical, diabolical denizens + of the deep who stalk about the corners of the cove all at the same +time.]]></key> <uc_key order="10"><![CDATA[TEN LYRICAL, SPHERICAL, DIABOLICAL DENIZ +ENS OF THE DEEP WHO STALK ABOUT THE CORNERS OF THE COVE ALL AT THE SA +ME TIME.]]></uc_key> <lc_key order="10"><![CDATA[ten lyrical, spherical, diabolical deniz +ens of the deep who stalk about the corners of the cove all at the sa +me time.]]></lc_key> </keys>


Actual output:

<?xml version="1.0" encoding="utf-8"?> <keys> <key order="01"><![CDATA[One hen]]></key> <uc_key order="01">ONE HEN</uc_key> <lc_key order="01"><![CDATA[one hen]]></lc_key> <key order="02"><![CDATA[Two ducks]]></key> <uc_key order="02">TWO DUCKS</uc_key> <lc_key order="02"><![CDATA[two ducks]]></lc_key> <key order="03"><![CDATA[Three squawking geese]]></key> <uc_key order="03">THREE SQUAWKING GEESE</uc_key> <lc_key order="03"><![CDATA[three squawking geese]]></lc_key> <key order="04"><![CDATA[Four limerick oysters]]></key> <uc_key order="04">FOUR LIMERICK OYSTERS</uc_key> <lc_key order="04"><![CDATA[four limerick oysters]]></lc_key> <key order="05"><![CDATA[Five corpulent porpoises]]></key> <uc_key order="05">FIVE CORPULENT PORPOISES</uc_key> <lc_key order="05"><![CDATA[five corpulent porpoises]]></lc_key> <key order="06"><![CDATA[Six pair of Don Alverzo's tweezers]]></key> <uc_key order="06">SIX PAIR OF DON ALVERZO'S TWEEZERS</uc_key> <lc_key order="06"><![CDATA[six pair of don alverzo's tweezers]]></l +c_key> <key order="07"><![CDATA[Seven thousand Macedonians in full battle a +rray]]></key> <uc_key order="07">SEVEN THOUSAND MACEDONIANS IN FULL BATTLE ARRAY</ +uc_key> <lc_key order="07"><![CDATA[seven thousand macedonians in full battl +e array]]></lc_key> <key order="08"><![CDATA[Eight brass monkeys from the ancient sacred + crypts of Egypt]]></key> <uc_key order="08">EIGHT BRASS MONKEYS FROM THE ANCIENT SACRED CRYPT +S OF EGYPT</uc_key> <lc_key order="08"><![CDATA[eight brass monkeys from the ancient sac +red crypts of egypt]]></lc_key> <key order="09"><![CDATA[Nine apathetic, sympathetic, diabetic old m +en on roller skates, with a marked propensity towards procrastination + and sloth]]></key> <uc_key order="09">NINE APATHETIC, SYMPATHETIC, DIABETIC OLD MEN ON +ROLLER SKATES, WITH A MARKED PROPENSITY TOWARDS PROCRASTINATION AND S +LOTH</uc_key> <lc_key order="09"><![CDATA[nine apathetic, sympathetic, diabetic ol +d men on roller skates, with a marked propensity towards procrastinat +ion and sloth]]></lc_key> <key order="10"><![CDATA[Ten lyrical, spherical, diabolical denizens + of the deep who stalk about the corners of the cove all at the same +time.]]></key> <uc_key order="10">TEN LYRICAL, SPHERICAL, DIABOLICAL DENIZENS OF TH +E DEEP WHO STALK ABOUT THE CORNERS OF THE COVE ALL AT THE SAME TIME.< +/uc_key> <lc_key order="10"><![CDATA[ten lyrical, spherical, diabolical deniz +ens of the deep who stalk about the corners of the cove all at the sa +me time.]]></lc_key> </keys>

  • Comment on [SOLVED] XML::Twig - '#CDATA' attribute in hashref disappears after first call to XML::Twig::Elt->new()
  • Select or Download Code

Replies are listed 'Best First'.
Re: XML::Twig - '#CDATA' attribute in hashref disappears after first call to XML::Twig::Elt->new()
by haukex (Archbishop) on Jul 21, 2018 at 12:51 UTC
    Is this supposed to happen?

    Well, it appears to be intentional, the code includes:

    $CDATA = '#CDATA'; ... package XML::Twig::Elt; ... sub new ... if( $atts && defined $atts->{$CDATA}) { delete $atts->{$CDATA}; my $cdata= $class->new( $CDATA => @_); return $class->new( $gi, $atts, $cdata); }

    So new assumes that it's ok to modify the hashref. Whether this is good design is debatable, but if you want to just work with the module as is, the workaround provided by the AM here creates a shallow copy of the hash, so that new is free to delete keys. Alternatively, you could do what the above code is doing, that is, wrap the data in a CDATA yourself.

Re: XML::Twig - '#CDATA' attribute in hashref disappears after first call to XML::Twig::Elt->new()
by Anonymous Monk on Jul 21, 2018 at 02:56 UTC

    Is this supposed to happen? I did not see anything mentioning this in the CPAN docs... spoilers

    Sure, why not? Its constructor, it does what it wants , with the stuff you give it , and with the stuff it gives you

    spoiler spoiler spoiler

    Yeah spoiler tags are for spoilers, not to hide your questions

      my $uc_element = XML::Twig::Elt->new('uc_key', {%$attributes}, uc $text);