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

I need to load, manipulate, and save a data file in the following format:
Arbitrary Number of Propertys = value; Arbitrary Number of Propertys = value; Arbitrary Object group { Arbitrary Number of Propertys = value; Arbitrary Number of SubOjbects { Arbitraty Number of Propertys = value; Arbitraty Number of Propertys = value; SubObject { etc... } SubOjbect { etc... } } } Object...
Objects sometimes refer to other objects (when they do they require an index of that object's type within it's parent). It's basically a small relational database.

In any case, I was wondering if anyone recognizes the data structure. Is it a standard type? Does anyone knows of a pre-existing module that I could use to load, manipulate, and save that structure?

I can build my own OO solution (I've been doing my homework), but it'd be nice to have something to start with.

Thanks,

Nick As an aside, given '$r_test = [$object->[$i]]', is there a method or function to find $i or @object if all you have is $r_test?

Edited by BazB: added additional code tags.

Replies are listed 'Best First'.
Re: MS XAct XAP Data file parsing
by tachyon (Chancellor) on Apr 11, 2004 at 10:21 UTC

    The 'structure' is just a typical object that embeds copies of itself. You typically use recursion to navigate such an object. Such a structure is often called a a tree. If you think about it the file system is a direct parallel with your structure. The properties are analogous to files and the subobjects are analogous to directories. Search CPAN for Tree to see lots of options.

    The answer to your aside in literal form is no. If you store a literal value that is what you store. You could store a reference and possibly dig up the info. The question would be why?

    The data structure you show could be represented in perl like this (there are other options). Perl can manipulate it. The advantage of embeded objects is that you can recursively call methods on the objects. Data::Dumper Storable FreezeThaw or YAML will all let you serialize it into a stream you can write to disk, read from disk and use to restore your object. I use Storable mostly.

    package Object; sub new { bless { _props => {}, _objs => [] }, shift }; sub add_prop { my ( $self, $prop, $value ) = @_; $self->{_props}->{$prop} = $value; } sub add_subobject { my ( $self, @obj ) = @_; push @{$self->{_objs}}, @obj; } my $base = new Object; my $sub1 = new Object; my $sub2 = new Object; my $subsub = new Object; $sub1->add_prop( sub1 => 1 ); $sub2->add_prop( sub2 => 1 ); $subsub->add_prop( deep => 1 ); $sub1->add_subobject( $subsub ); $base->add_prop( foo => 1 ); $base->add_prop( bar => 2 ); $base->add_subobject( $sub1, $sub2 ); use Data::Dumper; print Dumper $base; __DATA__ $VAR1 = bless( { '_objs' => [ bless( { '_objs' => [ bless( { '_objs' = +> [], '_props' +=> { + 'deep' => 1 + } }, 'Object' + ) ], '_props' => { 'sub1' => 1 } }, 'Object' ), bless( { '_objs' => [], '_props' => { 'sub2' => 1 } }, 'Object' ) ], '_props' => { 'foo' => 1, 'bar' => 2 } }, 'Object' );

    cheers

    tachyon

      Here is a naive parse function that receives reference to trimmed file lines.

      sub ParseXAP { my $lines = shift; my @props = (); my @children = (); while( scalar( @{$lines} ) ) { my $line = shift @{$lines}; if( length($line) ) { last if $line eq '}'; if( $line =~ /(.*) = (.*);/ ) { push @props, { 'name' => $1, 'value' => $2 }; } else { my $type = $line; $line = shift @{$lines}; die unless $line eq '{'; my $child = ParseXAP( $lines ); $child->{type} = $type; push @children, $child; } } } return { 'props' => \@props, 'children' => \@children }; }
Re: MS XAct XAP Data file parsing
by tilly (Archbishop) on Apr 11, 2004 at 07:36 UTC
    First of all the word is Arbitrary, not Arbitraty.

    As for the format, I don't recognize it, and your verbal description it is not as helpful as a short example of the format and how think that it should be interpreted. (And yes, you'll likely have to roll my own solution.)

    To answer your aside, there is no way within Perl to discover what array, or where in that array, a particular variable was copied from. Indeed the variable might be in many different arrays. If you want to get access to that information later, you have to arrange to keep it associated with the variable in some way.