Syrkres has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a web-app which I would like to collect information and then dump to an XML file.

I started with an XML file that I created (by hand). I can easily read it in via XML::Simple which loads it into a nice data structure (dumped with Data::Dumper).

I then started to think OO, and break sub elements of the XML structure down into objects.

I've written a few Perl Objects (been a while) breaking things down into separate classes(packages).

But when I dump the base object through data dumper, it has all the "bless" structures in there. I had hoped to come up with a structure similar to the one that was created by reading in the XML file.

So I guess the question is, is there a way to create objects within Perl and have the data structure come out similar.

Simple Sample of the XML:

<map> <location name="test"> <items> <item> <desc>some item1</desc> </item> <item> <desc>some item2</desc> </item> </items> <features> <desc>...</desc> </features> </location> </map>
Which loads nicely into by XML::Simple:
$VAR1 = { 'location' => { 'items' => { 'item' => [ { 'desc' => 'some i +tem1' }, { 'desc' => 'some i +tem2' } ] }, 'features' => { 'desc' => '...' }, 'name' => 'test' } };
When I try to create it with objects, and sub-objects I get the types and bless(...) stuff mixed in. The inital objects were Features and Item.

I figure I could create my own XML::Parser but that is more work than I had hoped, also Simple already does a great job.

Please help

Replies are listed 'Best First'.
Re: Objects and Data structure similar to XML
by Joost (Canon) on Jan 29, 2004 at 01:25 UTC
    When I try to create it with objects, and sub-objects I get the types and bless(...) stuff mixed in. The inital objects were Features and Item.
    I'm not sure if you want to read the XML as objects or output objects as XML or both, but if you're happy with the data structure that XML::Simple gives you, why bother converting that to/from objects at all?

    On the other hand, if you like Data::Dumper, there's no reason to use XML. :-)

    If you just want your XML data split into objects, you could always use some other, object-oriented XML parser (i.e. XML::Twig)

    Ps: I tried to find some kind of Perl "object serializer" that reads and writes XML, but I could not find it immediately. (It's 2:30 at night here, so I'm tired) Others here might have more info, or you could try searching CPAN for it yourself.

    Joost.

Re: Objects and Data structure similar to XML
by Roger (Parson) on Jan 29, 2004 at 04:51 UTC
    You could use XML::Dumper instead...
    use strict; use warnings; use CGI; use Data::Dumper; use XML::Dumper; my $cgi = new CGI; $cgi->{dummy} = new CGI; my $serialized = pl2xml($cgi); print "$serialized\n"; my $deserialized = xml2pl($serialized); print Dumper($deserialized);
    And the output -
    <perldata> <hashref blessed_package="CGI"> <item key=".charset">ISO-8859-1</item> <item key=".fieldnames"> <hashref> </hashref> </item> <item key=".parameters"> <arrayref memory_address="0x1950ba0"> </arrayref> </item> <item key="dummy"> <hashref blessed_package="CGI"> <item key=".charset">ISO-8859-1</item> <item key=".fieldnames"> <hashref> </hashref> </item> <item key=".parameters"> <arrayref memory_address="0x1ad737c"> </arrayref> </item> <item key="escape">1</item> </hashref> </item> <item key="escape">1</item> </hashref> </perldata> $VAR1 = bless( { '.parameters' => [], '.charset' => 'ISO-8859-1', 'dummy' => bless( { '.parameters' => [], '.charset' => 'ISO-8859-1', '.fieldnames' => {}, 'escape' => '1' }, 'CGI' ), '.fieldnames' => {}, 'escape' => '1' }, 'CGI' );

Re: Objects and Data structure similar to XML
by inman (Curate) on Jan 29, 2004 at 10:44 UTC
    This answer is from a language agnostic OO point of view.

    What I think that you are describing is serialisation of objects using XML as the data repository. The same technique is used with files, databases etc.

    One way to do this is to derive all classes from a single base class that implements a method along the lines of toXML(). All of the other classes implement the same method specialised according to their needs. When you want to write the structure, call toXML() at the top level and XML cascades out.

    In your example, the map object is at the top level. It's toXML() function writes the <map> tag and then calls the toXML() function on the location object - which in turn writes out it's own tags and calls toXML() on child objects.

    The reverse process is slightly more complicated since you need to handle potential defects in the data stream. In general though, a fromXML() method will read from the XML stream and instantiate objects etc. To do this properly, you will also want to validate your XML against a schema which will highlight incorrect XML before it is parsed.