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):
Now let's say that you want to get the first addres of the 2 servers (in XML::Simple):## 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>
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().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} ;
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:
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.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}
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:
To get the content you just get foo, and use 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' } );
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".
|
|---|