in reply to XML::Simple and Adding Nested Elements

Hello all, Looking for help adding additional nested elements to my data structure for eventual output with XML:Simple. Here are the significant portions of my code:
use XML::Simple; my $xs = XML::Simple->new( ForceArray => 1, KeepRoot => 1, NoAttr => 1 +, KeyAttr => [] ); my $data = { 'Things' => { 'Thing' => [] } }; ... push @{ $data->{Things}->{Thing} }, { 'Item' => $var1, 'Number' => $var2, 'Details' => { 'Detail' => { 'Color' => $var3 } }, }; ... push @{ $data->{Things}->{Thing} }, { 'AdditionalInfo' => { 'Info' => $var4, 'Stuff' => $var5, 'MoreDetails' => { 'ExtraColor' => $var6 } } };
I'd like to add one or more chunks of 'additional info' as needed. I'd like my resulting XML to look like this:
<Things> <Thing> <Item>Item1</Item> <Number>123</Number> <Details> <Detail> <Color>Blue</Color> </Detail> </Details> <AdditionalInfo> <Info>data</Info> <Stuff>moredata</Stuff> <MoreDetails> <ExtraColor>Purple</ExtraColor> </MoreDetails> </AdditionalInfo> </Thing> </Things>
How can I add a hash of additional infomation to a specific Item? When I run the code above the 'AdditionInfo' hash gets appended to the end of the data structure, which makes sense. How do I add data deeper than the initial data structure declaration?
Thanks for any insight provided. I've already read perldata, BTW...

Rob

Replies are listed 'Best First'.
Re: XML::Simple and Adding Additional Nested Elements
by psini (Deacon) on May 23, 2008 at 08:52 UTC

    Obviously you can do this:

    push @{ $data->{Things}->{Thing} }, { 'Item' => $var1, 'Number' => $var2, 'Details' => { 'Detail' => { 'Color' => $var3 } }, 'AdditionalInfo' => { 'Info' => $var4, 'Stuff' => $var5, 'MoreDetails' => { 'ExtraColor' => $var6 } } };

    But probably it is not what you really want. If the real question is "How can I dinamically build the structure that will generate my XML?", the answer is not so simple (aka, I can't make it for you :)):

    The right path to enlightment is to understand how complex data structures work in perl (your example id a HoHoHoHoH, not the very simplest) so you can handle them in a better way

    As an example, the following code probably do what you expect:

    $struc={ 'Item' => $var1, 'Number' => $var2, 'Details' => { 'Detail' => { 'Color' => $var3 } } } $struc->{AdditionalInfo}={ 'Info' => $var4, 'Stuff' => $var5, 'MoreDetails' => { 'ExtraColor' => $var6 } }; push @{ $data->{Things}->{Thing} },$struc;

    Not sure, I can't try it now

    Rule One: Do not act incautiously when confronting a little bald wrinkly smiling man.

      Thank you. That's a good idea. One last question. How would I find a specific Item? I was thinking along these lines:
      if ($data{Things}{Thing}{Item} = "aValue") { ...

        That code will not work because your structure is an array of reference.;/p>

        You can do if ($data[0]->{Things}->{Thing}->{Item} == "aValue")

        I strongly suggest you see Data Structures in the Q&A section of the monastery.

        Rule One: Do not act incautiously when confronting a little bald wrinkly smiling man.

        if ($data{Things}{Thing}{Item} = "aValue") {

        That would most likely not do what you want as it assigns "aValue" to the respective hash entry... :) — remember: eq is for string comparison.