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

Consider :

use XML::Simple; my $struct = XMLin( \*DATA ); print XMLout($struct, noattr => 1 ); __DATA__ <myconfig_data name="aaa" > <level1 my_att="somestring"> <value>hello1</value> </level1> <level2> <value other_att="bbb">hello2</value> </level2> <level3> <value>hello3</value> </level3> </myconfig_data>

Gives result ( almost as desired ) :

<opt> <name>aaa</name> <level1> <my_att>somestring</my_att> <value>hello1</value> </level1> <level2> <name>value</name> <content>hello2</content> <other_att>bbb</other_att> </level2> <level3> <value>hello3</value> </level3> </opt>

First question : Why do I have element 'opt' not <myconfig_data> at the docroot level ?

My main question : Can this be done within XML::Twig ? My reason being, for some twig handlers, I wish to convert all attributes to tags...

The nearest I can get is as follows :

use Data::Dumper; use strict; use XML::Twig; my $xml_twig = XML::Twig->new( pretty_print => 'indented', NoLWP => 1, discard_spaces => 1, ); $xml_twig->parse ( \*DATA ) || die "\nError parsing data $@\n"; my $struct=$xml_twig->simplify( noattr => 1 ); print Dumper($struct); __DATA__ <myconfig_data name="aaa" > <level1 my_att="somestring"> <value>hello1</value> </level1> <level2> <value other_att="bbb">hello2</value> </level2> <level3> <value>hello3</value> </level3> </myconfig_data>
This creates the following structure :
$VAR1 = { 'level1' => { 'value' => 'hello1' }, 'level2' => { 'value' => 'hello2' }, 'level3' => { 'value' => 'hello3' } };

Clearly this isnt correct. Variuos combinations of noattr =>0, / keeproot / keepattr havent helped.

Also, if the data structure was correct, how do I then use this to output my XML ?

Thanks.

Replies are listed 'Best First'.
Re: XML::Simple $elt->noattr is there an equivalent using XML::Twig
by mirod (Canon) on Mar 01, 2006 at 05:59 UTC
    First question : Why do I have element 'opt' not myconfig_data at the docroot level ?

    You need to use the KeepRoot option I think.

    More generally, using simplify in XML::Twig is a 1 way street: you can get a data structure from an element, but there is no going back. The method is designed to help people used to XML::Simple to be able to use techniques they are familiar with, when extracting data from XML. If you want to work with the twig and turn attributes into elements, then you will have to do it yourself:

    #totally untested! sub att_to_children { my( $elt)= @_; foreach my $att ($elt->att_names) { $elt->insert_new_elt( last_child => $att, $elt->att); } $elt->del_atts; }
      Thanks, KeepRoot works fine, but is for XML::Simple only..

      The example works OK ( need to use $elt->{att'}->{$att} for a value though ) - is this the same as the method 'att_to_field' ?

      ( I think so having looked at the code but would like to confirm still being a newbie )

      Thanks

        need to use $elt->{att'}->{$att} for a value though

        Actually $elt->att( $att) is what you want, to use an accessor instead of assuming that the attributes are in a hash (they are) and will always be (there is no guarantee about that anywhere in the docs). (end of the rant ;--)

        is this the same as the method 'att_to_field'

        Yes it is! And I had completely forgotten about this method. Thanks for reminding me of its existence. That will teach me to write more methods than can fit in my head.