Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

perl Data structure to XML

by Hosen1989 (Scribe)
on May 27, 2015 at 11:50 UTC ( [id://1127983]=perlmeditation: print w/replies, xml ) Need Help??

perl Data structure to XML

Hi ALL.

I like to share with you solution for issue I had face it and come with way to solve it.

I was in need of some module that take any kind of hash or array or any combination of those two and convert them to xml file.

will, yes there are other module that do this task but not as need it.

so here my way to do this task:

also please point to any error in my code or any other best way to do the same thing. ^_^

use strict; use warnings; use XML::LibXML; my %TV = ( flintstones => { series => "flintstones", nights => [ "monday", "thursday", "friday" ], members => [ { name => "fred", role => "husband", age => 36, }, { name => "wilma", role => "wife", age => 31, }, { name => "pebbles", role => "kid", age => 4, }, ], }, jetsons => { series => "jetsons", nights => [ "wednesday", "saturday" ], members => [ { name => "george", role => "husband", age => 41, }, { name => "jane", role => "wife", age => 39, }, { name => "elroy", role => "kid", age => 9, }, ], }, simpsons => { series => "simpsons", nights => [ "monday" ], members => [ { name => "homer", role => "husband", age => 34, }, { name => "marge", role => "wife", age => 37, }, { name => "bart", role => "kid", age => 11, }, ], }, ); my $xmlString = HASH2XML(\%TV,'TV_SERIES'); print $xmlString; ###################################################################### +######################## sub HASH2XML{ my ($inHashRef) = $_[0]; my ($inName) = $_[1]; if(!defined $inName){$inName = 'rootNode';} my $doc = XML::LibXML::Document->new('1.0', 'utf-8'); # to + create XML doc my $rootNode = $doc->createElement("$inName"); # to create xml +root node $rootNode->setAttribute('Profile_id'=> "$inName"); # add some A +ttribute to the node _OBJ2XML_($doc,$rootNode,$inHashRef,$inName); $doc->setDocumentElement($rootNode); # print $doc->toString(); return $doc->toString(1); } sub _OBJ2XML_{ my ($doc) = $_[0]; my ($inNode) = $_[1]; my ($inRef) = $_[2]; my ($inName) = $_[3]; if(!defined $inName){$inName = 'Node';} if(ref($inRef) eq 'HASH'){ for my $key (sort keys %{$inRef}) { if(ref($inRef->{$key}) eq 'HASH'){ my $tag = $doc->createElement($key); # $tag->setAttribute('dataType'=> "HASH"); $inNode->appendChild($tag); _OBJ2XML_($doc,$tag,$inRef->{$key},$key); }else{ _OBJ2XML_($doc,$inNode,$inRef->{$key},$key); } } }elsif(ref($inRef) eq 'ARRAY'){ my $Len = @{$inRef}; for(my $i = 0; $i < $Len; $i++){ if(ref(@{$inRef}[$i]) eq 'HASH' or ref(@{$inRef}[$i]) eq ' +ARRAY'){ my $tag = $doc->createElement($inName); # $tag->setAttribute('dataType'=> "ARRAY"); $inNode->appendChild($tag); _OBJ2XML_($doc,$tag,@{$inRef}[$i],$inName); }else{ _OBJ2XML_($doc,$inNode,@{$inRef}[$i],$inName); } } }elsif(ref($inRef) eq 'CODE'){ print "--End to CODE ref @ LINE:".__LINE__."\n"; return 0; }elsif(ref($inRef) eq 'SCALAR'){ print "--End to SCALAR ref @ LINE:".__LINE__."\n"; return 0; }else{ my $tag = $doc->createElement($inName); # $tag->setAttribute('dataType'=> "data"); $tag->appendTextNode($inRef); $inNode->appendChild($tag); return 0; } return 0; }

-----------------------------------------------------------------

and below is the sample for the output:

# ------------------------------------------# # the XML output after doing pretty print # # ------------------------------------------# <?xml version="1.0" encoding="utf-8"?> <TV_SERIES Profile_id="TV_SERIES"> <flintstones> <members> <age>36</age> <name>fred</name> <role>husband</role> </members> <members> <age>31</age> <name>wilma</name> <role>wife</role> </members> <members> <age>4</age> <name>pebbles</name> <role>kid</role> </members> <nights>monday</nights> <nights>thursday</nights> <nights>friday</nights> <series>flintstones</series> </flintstones> <jetsons> <members> <age>41</age> <name>george</name> <role>husband</role> </members> <members> <age>39</age> <name>jane</name> <role>wife</role> </members> <members> <age>9</age> <name>elroy</name> <role>kid</role> </members> <nights>wednesday</nights> <nights>saturday</nights> <series>jetsons</series> </jetsons> <simpsons> <members> <age>34</age> <name>homer</name> <role>husband</role> </members> <members> <age>37</age> <name>marge</name> <role>wife</role> </members> <members> <age>11</age> <name>bart</name> <role>kid</role> </members> <nights>monday</nights> <series>simpsons</series> </simpsons> </TV_SERIES>

Replies are listed 'Best First'.
Re: perl Data structure to XML
by sundialsvc4 (Abbot) on May 29, 2015 at 14:22 UTC

    The first thing that I observe from looking at your Perl data-structure, vs. the resulting XML output, is that the two are not the same.   For example:

    members => [ { name => "george", role => "husband", age => 41, }, { name => "jane", role => "wife", age => 39, }, { name => "elroy", role => "kid", age => 9, },
    would correspond to a list of three nodes, each having three attributes apiece.   Any XML-writer would immediately produce such an XML output.

    Given that this is not what you want, you should transform your hash so that its structure does match what you want.   In place of three hashes, create three arrays.   (None of the elements in your desired output are to have any “attributes” at all.)   Consult the Perldoc to see what the data structure needs to look like.   Once you have done this, and have done it in the most simple-and-obvious way possible, you can hand this data structure to an XML-writer and get your XML.

      Hi,

      Well, we I was creating this code I kept this idea in my mind: I do not know the structure of the data beforehand, It can be any nasty hash in array in array in hash.... and so on.

      I can see your point here (about the attributes), And it raise new Q here:

      How can we decide what is Node and what is attribute without knowing the hash structure beforehand?

      we can add keywords to determine what is node and what is attribute, or maybe you have better idea. any help.

      Hosen

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1127983]
Approved by erzuuli
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-04-19 06:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found