Falantar has asked for the wisdom of the Perl Monks concerning the following question:
Hello, In the past couple of days I managed to make a script that parses through a specific XML file and returns only a few values. To be more specific, the data is formated like this:
__DATA__ <!-- Dog section --> <object type="Dog" > <property name="id" value="0" /> <property name="name" value="REX" /> <property name="status" value="alive" /> <property name="mode" value="owned" /> <property name="dog_breed_id" value="0" /> <property name="dog_breed_name" value="Husky" /> <property name="capacity" value="105" /> <property name="size" value="big" /> <property name="location" value="canada" /> </object >
This is just an example and not the actual values but you get the idea. There will also be several of these "objects" one after another. The script I made used the Tree style, I'm now trying to create one using Stream. The only info I want to extract is the name, the dog_breed_id, and the dog_breed_name. I would like the output to be simple and only seperated by commas, like this:
REX,0,Husky
I'm a novice programmer but I'm a pretty quick learner so don't be shy. My main purpose is to make it run faster but also to learn how to use different methods of parsing data.
Edit: For those interested, I used XML::Rules, this is what the final code looks like.
#!/usr/bin/perl -w use strict; use warnings; use vars qw/ %options /; use Getopt::Std; use XML::Rules; # How to use the script sub Usage(){ print STDERR " Usage : $0 [-arg file] arg: -i : load information from XML file \n"; exit 2; } my $opt_string = 'i:'; my $File; my %options; getopts("$opt_string", \%options ); Usage unless ( %options ); foreach ( (my $key) = (keys %options) ){ $File = $options{$key}; } Usage unless(-f $File); my @rules = ( object => sub { if( $_[1]{type} eq 'dog' ){ print join(",", @{$_[1]}{qw(dog_brd_id dog_brd_name name)}),"\n"; return; } elsif($_[1]{type} eq 'cat'){ XML::Rules->return_nothing; } }, property => sub {$_[1]->{name} => $_[1]->{value}}, ); my $xr = XML::Rules->new( rules => \@rules, stripspaces => 2 ); $xr->parsefile($File);
This obviously depends that the Dog section comes before the Cat section. Using this method though, I was able to bring the real time from 20s to 0.5s. Thanks to everyone who helped!!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: XML::Parser using stream
by toolic (Bishop) on Aug 17, 2011 at 16:33 UTC | |
by Falantar (Initiate) on Aug 17, 2011 at 18:23 UTC | |
by toolic (Bishop) on Aug 17, 2011 at 18:36 UTC | |
by Falantar (Initiate) on Aug 17, 2011 at 18:50 UTC | |
|
Re: XML::Parser using stream
by runrig (Abbot) on Aug 17, 2011 at 19:45 UTC | |
by Falantar (Initiate) on Aug 18, 2011 at 11:52 UTC | |
|
Re: XML::Parser using stream
by Perlbotics (Archbishop) on Aug 17, 2011 at 16:53 UTC | |
|
Re: XML::Parser using stream
by Falantar (Initiate) on Aug 17, 2011 at 17:10 UTC |