![]() |
Want true instantiated objects from XML
I've had a need for this at points in the past, but was always able to
code around it (and still could even now), but I'd really like to be able to do this, and I can't find anything out there that does this exactly as I want. (Which tends to make me believe what I want wouldn't be as immediately useful as maybe I would think it to be, but...?!) Given an object defined as this: package Person; use strict; use warnings qw( all ); sub new { my $proto = shift; my $class = ref $proto || $proto; my %attrs = @_; my $self = {}; # Nevermind the error checking for attributes right now. $self->{__name} = $attrs{name}; $self->{__age} = $attrs{age}; bless $class, $self; return $self; } # RW attributes. sub name { $s = shift; $s->{__name} = shift if @_; return $s- >{__name} } sub age { $s = shift; $s->{__age} = shift if @_; return $s->{__age} } # Methods. sub sayName { print "My name is: " . shift->{__name} . "\n" } sub sayAge { print "I am " . shift->{__age} . " years old.\n" } 1; I want to be able to read the following XML and create instances of Person from each instance in the XML: <xml> <People> <Person name="John Doe" age="22" /> <Person name="Jane Doe" age="23" /> <Person name="Maxx Doogan" age="10" /> </People> </xml> So I get an array of Person objects which I can then write: my @people; # Hold the array of Person object created from the XML above. for my $person (@people) { $person->sayName(); $person->sayAge(); } I've looked through SOAP::Lite (and SOAP::Serialize and SOAP::Deserialize). I'm a fairly frequent user of XML::Simple, but Simple doesn't do the above (AFAIK). SURELY *something* like this is "out there" (read "CPAN") but I can't seem to find it; only things close to it (like SOAP::SOM objects that require an xpath of sorts and my methods are still not available through an instantiated method of just the data [object attributes] in XML.) Thanks! /usr/ceo |
Re: Want true instantiated objects from XML
/usr/ceo <newsbot@cox.net> wrote:
> I've looked through SOAP::Lite (and SOAP::Serialize and > SOAP::Deserialize). I'm a fairly frequent user of XML::Simple, but > Simple doesn't do the above (AFAIK). SURELY *something* like this is > "out there" (read "CPAN") but I can't seem to find it; only things > close to it (like SOAP::SOM objects that require an xpath of sorts and > my methods are still not available through an instantiated method of > just the data [object attributes] in XML.) I would do it with XML::Twig, myself, though there are other options. #!/usr/bin/perl use strict; use warnings use Person; use XML::Twig; my $twig = XML::Twig->new(); $twig->parse(\*DATA); my ($name, $age); my $person; my @personslist; my @xmlpersons = $twig->root->descendants('Persons'); foreach my $element (@xmlpersons) { $name = $element->att('name'); $age = $element->att('age'); $person = Person->new('name' => $name, 'age' => $age); push(@personslist,$person); } __DATA__ <xml> <People> <Person name="John Doe" age="22" /> <Person name="Jane Doe" age="23" /> <Person name="Maxx Doogan" age="10" /> </People> </xml> ########## You're looking for something like that? -- Zed Pobre <zed@resonant.org> a.k.a. Zed Pobre <zed@debian.org> PGP key and fingerprint available on finger; encrypted mail welcomed. |
Re: Want true instantiated objects from XML
On Sun, 12 Oct 2008 14:01:14 -0700 (PDT), "/usr/ceo" <newsbot@cox.net> wrote:
>I've had a need for this at points in the past, but was always able to >code around it (and still could even now), but I'd really like to be >able to do this, and I can't find anything out there that does this >exactly as I want. (Which tends to make me believe what I want >wouldn't be as immediately useful as maybe I would think it to be, >but...?!) > >Given an object defined as this: > >package Person; > >use strict; >use warnings qw( all ); > >sub new { > my $proto = shift; > my $class = ref $proto || $proto; > my %attrs = @_; > my $self = {}; > > # Nevermind the error checking for attributes right now. > > $self->{__name} = $attrs{name}; > $self->{__age} = $attrs{age}; > > bless $class, $self; > > return $self; >} > ># RW attributes. > >sub name { $s = shift; $s->{__name} = shift if @_; return $s- >>{__name} } >sub age { $s = shift; $s->{__age} = shift if @_; return $s->{__age} } > ># Methods. > >sub sayName { print "My name is: " . shift->{__name} . "\n" } >sub sayAge { print "I am " . shift->{__age} . " years old.\n" } > >1; > The above is all very impressive. What do you want to do? >I want to be able to read the following XML and create instances of >Person from each instance in the XML: > ><xml> ><People> > <Person name="John Doe" age="22" /> > <Person name="Jane Doe" age="23" /> > <Person name="Maxx Doogan" age="10" /> ></People> ></xml> > So XML parsing is holding you up? >So I get an array of Person objects which I can then write: > >my @people; # Hold the array of Person object created from the XML >above. > >for my $person (@people) { > $person->sayName(); > $person->sayAge(); >} > >I've looked through SOAP::Lite (and SOAP::Serialize and >SOAP::Deserialize). I'm a fairly frequent user of XML::Simple, but >Simple doesn't do the above (AFAIK). SURELY *something* like this is >"out there" (read "CPAN") but I can't seem to find it; only things >close to it (like SOAP::SOM objects that require an xpath of sorts and >my methods are still not available through an instantiated method of >just the data [object attributes] in XML.) > >Thanks! >/usr/ceo rxparse version 2 sln |
Re: Want true instantiated objects from XML
On Oct 12, 6:17*pm, Zed Pobre <z...@resonant.org> wrote:
> /usr/ceo <news...@cox.net> wrote: > > I've looked through SOAP::Lite (and SOAP::Serialize and > > SOAP::Deserialize). *I'm a fairly frequent user of XML::Simple, but > > Simple doesn't do the above (AFAIK). *SURELY *something* like this is > > "out there" (read "CPAN") but I can't seem to find it; only things > > close to it (like SOAP::SOM objects that require an xpath of sorts and > > my methods are still not available through an instantiated method of > > just the data [object attributes] in XML.) > > I would do it with XML::Twig, myself, though there are other options. > > #!/usr/bin/perl > use strict; use warnings > use Person; > use XML::Twig; > > my $twig = XML::Twig->new(); > $twig->parse(\*DATA); > > my ($name, $age); > my $person; > my @personslist; > my @xmlpersons = $twig->root->descendants('Persons'); > > foreach my $element (@xmlpersons) > { > * * $name = $element->att('name'); > * * $age = $element->att('age'); > * * $person = Person->new('name' => $name, 'age' => $age); > * * push(@personslist,$person); > > } > > __DATA__ > <xml> > <People> > * * <Person name="John Doe" age="22" /> > * * <Person name="Jane Doe" age="23" /> > * * <Person name="Maxx Doogan" age="10" /> > </People> > </xml> > > ########## > > You're looking for something like that? Well that's definitely pretty nice. It's about halfway between what I want and what I thought I was going to have to do, which was close to what you wrote -- I just hadn't looked at XML::Twig. This is close enough to what I want without providing a schema upfront (which is why I think it would be a little difficult to write something smart enough to marshall to and from XML since XML is for all intents and purposes, free-format.) I think the XML::Twig hit will be helpful and I'll probably do that. Thanks! /usr/ceo |
Re: Want true instantiated objects from XML
On Oct 12, 6:46*pm, s...@netherlands.com wrote:
> On Sun, 12 Oct 2008 14:01:14 -0700 (PDT), "/usr/ceo" <news...@cox.net> wrote: > >I've had a need for this at points in the past, but was always able to > >code around it (and still could even now), but I'd really like to be > >able to do this, and I can't find anything out there that does this > >exactly as I want. *(Which tends to make me believe what I want > >wouldn't be as immediately useful as maybe I would think it to be, > >but...?!) > > >Given an object defined as this: > > >package Person; > > >use strict; > >use warnings qw( all ); > > >sub new { > > * my $proto = shift; > > * my $class = ref $proto || $proto; > > * my %attrs = @_; > > * my $self = {}; > > > * # Nevermind the error checking for attributes right now. > > > * $self->{__name} = $attrs{name}; > > * $self->{__age} = $attrs{age}; > > > * bless $class, $self; > > > * return $self; > >} > > ># RW attributes. > > >sub name { $s = shift; $s->{__name} = shift if @_; return $s- > >>{__name} } > >sub age { $s = shift; $s->{__age} = shift if @_; return $s->{__age} } > > ># Methods. > > >sub sayName { print "My name is: " . shift->{__name} . "\n" } > >sub sayAge { print "I am " . shift->{__age} . " years old.\n" } > > >1; > > The above is all very impressive. What do you want to do? > > >I want to be able to read the following XML and create instances of > >Person from each instance in the XML: > > ><xml> > ><People> > > * <Person name="John Doe" age="22" /> > > * <Person name="Jane Doe" age="23" /> > > * <Person name="Maxx Doogan" age="10" /> > ></People> > ></xml> > > So XML parsing is holding you up? No, I can parse most of the XML I need with XML::Simple. The point is, I don't really want the hashed structure that XML::Simple provides, even though I can munge the parsing with ForceGroup and other options. So no, the parsing isn't the issue. I want more of an XML "freeze / unfreeze" or serialize / deserialize (marshalling) solution. (Marshalling and s/d aren't always the same I realize...) > > > >So I get an array of Person objects which I can then write: > > >my @people; # Hold the array of Person object created from the XML > >above. > > >for my $person (@people) { > > * $person->sayName(); > > * $person->sayAge(); > >} > > >I've looked through SOAP::Lite (and SOAP::Serialize and > >SOAP::Deserialize). *I'm a fairly frequent user of XML::Simple, but > >Simple doesn't do the above (AFAIK). *SURELY *something* like this is > >"out there" (read "CPAN") but I can't seem to find it; only things > >close to it (like SOAP::SOM objects that require an xpath of sorts and > >my methods are still not available through an instantiated method of > >just the data [object attributes] in XML.) > > >Thanks! > >/usr/ceo > > rxparse version 2 I'll check that out as well, but the solution Zed offered was closer to what I was looking for. Close enough. Thanks! /usr/ceo |
Re: Want true instantiated objects from XML
On Oct 13, 1:57*am, "/usr/ceo" <news...@cox.net> wrote:
> On Oct 12, 6:46*pm, s...@netherlands.com wrote: > > > > > On Sun, 12 Oct 2008 14:01:14 -0700 (PDT), "/usr/ceo" <news...@cox.net> wrote: > > >I've had a need for this at points in the past, but was always able to > > >code around it (and still could even now), but I'd really like to be > > >able to do this, and I can't find anything out there that does this > > >exactly as I want. *(Which tends to make me believe what I want > > >wouldn't be as immediately useful as maybe I would think it to be, > > >but...?!) > > > >Given an object defined as this: > > > >package Person; > > > >use strict; > > >use warnings qw( all ); > > > >sub new { > > > * my $proto = shift; > > > * my $class = ref $proto || $proto; > > > * my %attrs = @_; > > > * my $self = {}; > > > > * # Nevermind the error checking for attributes right now. > > > > * $self->{__name} = $attrs{name}; > > > * $self->{__age} = $attrs{age}; > > > > * bless $class, $self; > > > > * return $self; > > >} > > > ># RW attributes. > > > >sub name { $s = shift; $s->{__name} = shift if @_; return $s- > > >>{__name} } > > >sub age { $s = shift; $s->{__age} = shift if @_; return $s->{__age} } > > > ># Methods. > > > >sub sayName { print "My name is: " . shift->{__name} . "\n" } > > >sub sayAge { print "I am " . shift->{__age} . " years old.\n" } > > > >1; > > > The above is all very impressive. What do you want to do? > > > >I want to be able to read the following XML and create instances of > > >Person from each instance in the XML: > > > ><xml> > > ><People> > > > * <Person name="John Doe" age="22" /> > > > * <Person name="Jane Doe" age="23" /> > > > * <Person name="Maxx Doogan" age="10" /> > > ></People> > > ></xml> > > > So XML parsing is holding you up? > > No, I can parse most of the XML I need with XML::Simple. *The point > is, I don't really want the hashed structure that XML::Simple > provides, even though I can munge the parsing with ForceGroup and > other options. *So no, the parsing isn't the issue. *I want more of an > XML "freeze / unfreeze" or serialize / deserialize (marshalling) > solution. *(Marshalling and s/d aren't always the same I realize...) > > > > > > > >So I get an array of Person objects which I can then write: > > > >my @people; # Hold the array of Person object created from the XML > > >above. > > > >for my $person (@people) { > > > * $person->sayName(); > > > * $person->sayAge(); > > >} > > > >I've looked through SOAP::Lite (and SOAP::Serialize and > > >SOAP::Deserialize). *I'm a fairly frequent user of XML::Simple, but > > >Simple doesn't do the above (AFAIK). *SURELY *something* like this is > > >"out there" (read "CPAN") but I can't seem to find it; only things > > >close to it (like SOAP::SOM objects that require an xpath of sorts and > > >my methods are still not available through an instantiated method of > > >just the data [object attributes] in XML.) > > > >Thanks! > > >/usr/ceo > > > rxparse version 2 > > I'll check that out as well, but the solution Zed offered was closer > to what I was looking for. *Close enough. > > Thanks! > /usr/ceo For those of you following along at home, there were some minor errors with the code I typed in off the top of my head for my example. blessing into $class is wrong. Using "strict" the $s variable in my accessors needed to be "my"'d. I hate it when I read a book or try to pull something from Usenet and it doesn't work due to unchecked errors on the part of the author! :-) :-( Here is the final XML::Twig solution, taking Zed's XML::Twig solution, adding in the Person package (just inline in this case) and correcting for a few errors (and making a few ticky-tack "the way I do things" changes to Zed's example which was fine as it was): #!/usr/bin/perl use strict; use warnings qw( all ); package Person; use strict; use warnings qw( all ); sub new { my $proto = shift; my $class = ref $proto || $proto; my %attrs = @_; my $self = {}; # Nevermind the error checking for attributes right now. $self->{__name} = $attrs{name}; $self->{__age} = $attrs{age}; bless $self, $class; return $self; } # RW attributes. sub name { my $s = shift; $s->{__name} = shift if @_; return $s- >{__name} } sub age { my $s = shift; $s->{__age} = shift if @_; return $s- >{__age} } # Methods. sub sayName { print "My name is: " . shift->{__name} . "\n" } sub sayAge { print "I am " . shift->{__age} . " years old.\n" } package main; use XML::Twig; my $twig = XML::Twig->new(); $twig->parse( \*DATA ); my @people; my @xmlpersons = $twig->root->descendants( 'Person' ); for my $element (@xmlpersons) { my $name = $element->att( 'name' ); my $age = $element->att( 'age' ); my $person = Person->new( name => $name, age => $age ); push @people, $person; } for my $person (@people) { print "-" x 10 . "\n"; $person->sayName(); $person->sayAge(); } __DATA__ <xml> <People> <Person name="John Doe" age="22" /> <Person name="Jane Doe" age="23" /> <Person name="Maxx Doogan" age="10" /> </People> </xml> Grüss! /usr/ceo |
| All times are GMT. The time now is 01:36 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.