Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Creating nested elements in XML::Smart

by cirrus (Initiate)
on Dec 11, 2012 at 23:41 UTC ( #1008430=perlquestion: print w/replies, xml ) Need Help??
cirrus has asked for the wisdom of the Perl Monks concerning the following question:

I have been trying to use XML Smart module to create some XML files and Iím having some problems getting element to nest properly. Iím new to this module I would appreciate if you could help me specify correct code that I need to use to create this simple XML structure:

<Shelf_Info> <switch Name="Puebla01"> <shelfType>7480</shelfType> <commentText>ATM Core switch</commentText> </switch> <switch Name="Puebla02"> <shelfType>7440</shelfType> <commentText>ATM access switch</commentText> </switch> </Shelf_Info>

So far I managed to create elements for one occurrence of switch data in the above example but I donít know how to get it to build the structure for second, third,Ö.occurrence. This is what I have:

my $XML = XML::Smart->new() ; $XML->{Shelf_Info} ; $XML->{Shelf_Info}{switch}{Name} = "$pp"; $XML->{Shelf_Info}{switch}{shelfType} = '15000'; $XML->{Shelf_Info}{switch}{shelfType}->set_node(1); $XML->{Shelf_Info}{switch}{commentText} = "$comment"; $XML->{Shelf_Info}{switch}{commentText}->set_node(2); $XML->save('test.xml') ;

So, how do I get it to create the second lot (switch Name="Puebla02Ē) without overriding the first one?

Regards Kon

Replies are listed 'Best First'.
Re: Creating nested elements in XML::Smart
by bitingduck (Chaplain) on Dec 12, 2012 at 08:02 UTC

    This seems to work:

    use strict; use warnings; use XML::Smart; my @pp=qw(Puebla01 Puebla02); my @shelf=qw(7480 7440); my @comment=("ATM Core switch","ATM access switch"); my $XML = XML::Smart->new() ; my $count=0; foreach (@pp){ $XML->{Shelf_Info}{switch}[$count]{Name} = "$_"; $XML->{Shelf_Info}{switch}[$count]{shelfType} = $shelf[$count]; $XML->{Shelf_Info}{switch}[$count]{shelfType}->set_node(1); $XML->{Shelf_Info}{switch}[$count]{commentText} = "$comment[$count +]"; $XML->{Shelf_Info}{switch}[$count]{commentText}->set_node(2); $count++; } $XML->save('test.xml') ;

    It seems to want array refs to iterate over nodes.

Re: Creating nested elements in XML::Smart
by Jenda (Abbot) on Dec 12, 2012 at 14:34 UTC
    use XML::Rules; my $parser = XML::Rules->new(rules => {}, ident => ' '); print $parser->toXML( Shelf_Info => { switch => [ {Name => "Puebla01", shelfType => [7480], commentText => ['ATM + Core switch']}, {Name => "Puebla02", shelfType => [7440], commentText => ['ATM + access switch']}, ] });

    Not XML::Smart though. It makes use of the fact that the value of a tag attribute may only be a single string, not a hash or array so it's clear that the shelfType and commentText must be a child tag, not an attribute. Generally XML::Rules attempts to create the simplest possible XML that'd contain the data and attribute is considered simpler than child tag.

    Update: With version 1.16 I just uploaded to CPAN, it'd be even simpler:

    use XML::Rules ToXML => { ident => ' ' }; print ToXML( Shelf_Info => { switch => [ {Name => "Puebla01", shelfType => [7480], commentText => ['ATM + Core switch']}, {Name => "Puebla02", shelfType => [7440], commentText => ['ATM + access switch']}, ] });

    You may now instantiate a parser and import a subroutine that'll call the specified method on that instance to simplify the usage.

    Enoch was right!
    Enjoy the last years of Rome.

Re: Creating nested elements in XML::Smart
by choroba (Chancellor) on Dec 14, 2012 at 07:01 UTC
    A solution using XML::XSH2, a wrapper around XML::LibXML.
    #!/usr/bin/perl use warnings; use strict; use XML::XSH2; package XML::XSH2::Map; use constant { TYPE => 0, COMMENT => 1, }; our %Shelves = ( Puebla01 => [7480, 'ATM Core switch'], Puebla02 => [7440, 'ATM access switch'], ); package main; xsh << '__XSH__'; create Shelf_Info ; for my $shelf in { sort keys %Shelves } { my $switch := insert element switch append /Shelf_Info ; cd $switch ; set @Name $shelf ; set shelfType { $Shelves{$shelf}[TYPE] } ; set commentText { $Shelves{$shelf}[COMMENT] } ; } save :f 'test.xml' ; __XSH__
    لսႽÜ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2017-04-24 09:45 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (438 votes). Check out past polls.