The first version of the module XML::Smart is in final stage. Before release it on CPAN I would like to show it at the monastery, and see what the monks think in this new way to access/create XML data, and test. Since I had good results in the last time that I did this, for the module Object::MultiType.

But what is XML::Smart? Is a smart, easy and powerful way to access/create XML files/data. Is easier than XML::Simple, more dynamic and integrated with the Perl syntax. But only after try it you will really know how good it can be! In the first look it seam to be simple, and should, but what is inside to make this crazy and funy way work is very complex! But let's talk about the code:

I will try to examplain how it works here, but the better way is to try it, and see the POD inside, that have some code examples. (links in the bottom).

Every one that have tried to use a HASH tree to access XML have big problems, specially when you don't know if in some point you have a HASH key, an ARRAY ref or another HASH ref. This is why when you create an XML::Simple object you have a lot of options to force ARRAY, cut the root node, etc... But you still need to know what structure your XML tree have, and to do that generally we look at the XML file (what is really wrong), or make a lot of codes to check!

To fix that and make everything automatically and easy, I think in a way to make a Perl object work in the same time as an HASH, ARRAY, SCALAR and CODE. What now lives in the module Object::MultiType, and is there for future ideas too, and for any monk. ;-P

A good example is to compare how to access this data in XML::Simple (a HASH tree), and XML::Smart (a HASH tree too, but actually you are accessing a tied HASH and a tied ARRAY that work together):

## The data: <?xml version="1.0" encoding="iso-8859-1"?> <hosts> <server os="linux" type="redhat" version="8.0"> <address>192.168.0.1</address> <address>192.168.0.2</address> </server> <server address="192.168.2.100" os="linux" type="conectiva" version= +"9.0"/> </hosts>
Now let's say that you want to get the first addres of the 2 servers (in XML::Simple):
my $xml = new XML::Simple(); my $tree = $xml->XMLin(DATA]); my $addr0 = $tree->{hosts}{server}[0]{address}[0] ; my $addr1 = $tree->{hosts}{server}[1]{address} ;
Note that in the first case ($addr0) you have an ARRAY ref in the key (since you have 2 addresses), so you need to use [0], but in the second you have a normal key (1 address), than just use the key name. But if you don't know when and where you have a HASH or an ARRAY, you need to check the reference before, or you can get errors, and your script die().

With XML::Smart is easy, since each point in the HASH tree is in the same time a HASH, an ARRAY, a SCALAR and a CODE! So you can make this:

my $XML = XML::Smart->new(DATA) ; my $addr0 = $XML->{hosts}{server}[0]{address}[0] ; ## return {addres +s}[0] ## ...or... my $addr0 = $XML->{hosts}{server}{address} ; ## return {addres +s}[0] my $addr1 = $XML->{hosts}{server}[1]{address} ; ## return {addres +s} ## ...or.. my $addr1 = $XML->{hosts}{server}[1]{address}[0] ; ## return {addre +ss}
You can see that when you have a normal key, and use [0], you actually get the {key}. Or when you have an ARRAY and call the {key} you get the [0] of the array! And when you access [1] but have a {key} you get UNDEF.

Or let's say that you want to get the address of the server with the 'type' 'conectiva', but don't know if it's the 1st or second in the DATA. So, you can use a search selection:

my $addr = $XML->{hosts}{server}('type','eq','conectiva'){address} ;

To get the CONTENT you don't need to use a key called content, you get it as a string:

## Data: <foo port="80">content<i>a</i><i>b</i></foo> ## Tree of the data: $HASH = ( foo => { i => ['a','b'] , CONTENT => 'content' } );
To get the content you just get foo, and use it as a string:
my $cont = $XML->{foo} ; ## ...or... my $cont = $XML->{foo}->content ; print "<<$cont>>\n" ; ## print: <<content>> $content .= 'x' ; ## Append data.

And to save your new data:

my $data = $XML->data ; ## Directly to the file: my $data = $XML->save('new.xml') ;

You can download it at: http://www.inf.ufsc.br/~gmpassos/XML-Smart-1.0.tar.gz
And the dependence module that make everything possible: http://www.inf.ufsc.br/~gmpassos/Object-MultiType-0.01.tar.gz (who got this need to get again, was updated)

See the POD and test.pl in the package! I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P

Graciliano M. P.
"The creativity is the expression of the liberty".


In reply to XML::Smart - Development in final stage. (beta is out) by gmpassos

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.