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

Hello Monks, After days of messing around with perl mods, trying to get them to work... I gave up and am trying to code it myself as it seems simple enough to parse this EXAMPLE DATA (XML:Simple simply won't work on my host and I don't have access to add other mods)

?xml version <GeocodeResponse> <status>OK</status> <result> <type>street_address</type> <formatted_address>1600 Amphitheatre Pkwy</formatted_address> <address_component> <long_name>1600</long_name> <short_name>1600</short_name> <type>street_number</type> </address_component>

I'm looking to create this example from LUA, unless theres an easier way to do this of course

mytable = { [GeocodeResponse] = { [result] = { [type] = "street address", [formatted_address] = "1600 Amphitheatre Pkwy", [address_component] = { [long_name] = 1600, [short_name] = 1600, [type] = "street_number" } } } };

I'm trying to build an array from the table data above by reading line by line and creating the appropriate array tree (I'm not sure of terminology as i'm use to LUA) I know the below code is a mess, its as clean as i'm able to make it from tutorials on the interwebz.

if(length($content) >= 10 && $content =~ m/\<status\>OK\<\/status\>/) +{ my @lines = split /\n/, $content; $depth=0; %myarray = (); $arrayKey = {}; foreach my $line (@lines) { if($line =~ m/\?xml version/) { # DO NOTHING } else { if($line =~ m/\<(.*)\>(.*)\<\/.*\>/) { $arrayLoc = \%myarray; for ($i = 1; $i < $depth; $i++) { local $k=$arrayKey[$i]; if(!$arrayLoc->{$k}) { $arrayLoc->{$k}=() } $arrayLoc=$arrayLoc{$k}; } } elsif($line =~ /^\s{0,4}\<\/(.*)\>/) { $depth--; $arrayKey[$depth]=$1; } elsif($line =~ /^\s{0,4}\<(.*)\>$/) { $depth++; $arrayKey[$depth]=$1; } } } }

I'm sure its easy for you all, but not me Thank-you *bow*

Replies are listed 'Best First'.
Re: recreating an array
by Anonymous Monk on Sep 08, 2011 at 21:00 UTC

    Hi :D

    After days of messing around with perl mods, trying to get them to work...

    It is easier/more important to resolve this issue of installing mods, monk, see Tutorials:A Guide To Installing Modules, installing modules non-interactively, in your home directory

    I gave up and am trying to code it myself as it seems simple enough to parse this EXAMPLE DATA

    Thats not valid xml, friend /*Mwahaha*

    (XML:Simple simply won't work on my host and I don't have access to add other mods) ...

    Sir, Yes, even you can use CPAN

    I'm looking to create this example from LUA, unless theres an easier way to do this of course

    And we should know lua syntax? Boy howdy

    Well, it looks close enough to this format, so you can use one of those solutions :D

    I'm trying to build an array from the table data above by reading line by line and creating the appropriate array tree

    Ok dawg, here you go, magic, Data::Lua - Parse variables out of Lua code.

    update: Sorry cat, too much magic, its kinda hard to install, needs Inline::Lua

    I'm sure its easy for you all, but not me Thank-you *bow*

    Yeah, copy/paste can be easier if you can grok how to use it, see Re^2: parsing XML fragments (xml log files) with... a regex

    XML::Simple is easier

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dumper; use XML::Simple; my $lua =<<'__LUA__'; <GeocodeResponse> <status>OK</status> <result> <type>street_address</type> <formatted_address>1600 Amphitheatre Pkwy</formatted_address> <address_component> <long_name>1600</long_name> <short_name>1600</short_name> <type>street_number</type> </address_component> </result> </GeocodeResponse> __LUA__ print Dumper( XMLin($lua, ) ), "\n\n"; __END__ $VAR1 = { 'status' => 'OK', 'result' => { 'formatted_address' => '1600 Amphitheatre Pkwy +', 'type' => 'street_address', 'address_component' => { 'short_name' => '1600 +', 'long_name' => '1600' +, 'type' => 'street_num +ber' } } };

    Don't feel jealous :D

    I'm a horsey with the bran of a turtlecat, dawg

      Thank-you for the reply, i'll read what you've written a couple times to decipher the code XML:Simple is easier for sure, but... sadly it only works on my own computer, not the target server. I've two hosts, both of which allow 'some' perl functions, but neither supplying all. Highly frusterating to make a bunch of 'working on my server code', then upload and only portions of it work on each host because of missing mods etc >.> Back to parsing your meanings :) *bow*

Re: recreating an array
by charlesboyo (Beadle) on Sep 08, 2011 at 21:07 UTC

    Your XML appears to be incomplete, hence unparseable by any decent XML parser.

    The code below uses a few regexes operation over the entire string. Note this will only work if your XML is spread across several lines as shown in the snippet you provided.

    use strict; # Load up your XML # This example ignores the obviously mangled <?xml ?> line at the top my $xml = qq( <GeocodeResponse> <status>OK</status> <result> <type>street_address</type> <formatted_address>1600 Amphitheatre Pkwy</formatted_address> <address_component> <long_name>1600</long_name> <short_name>1600</short_name> <type>street_number</type> </address_component> ); # Before print "Before the transformation: \n"; print "$xml\n"; # Regexes to re-write the text # replace all closing tags, which must run to the end of the line $xml =~ s[</.+$][",]mg; # rewrite opening tags in as hash keys - first part $xml =~ s[<]["]mg; # concluding part of rewriting opening tags $xml =~ s[>][" => "]mg; # handle elements that contain non-text elements $xml =~ s[=> "$][=> {]mg; # the final closing tag is surplus, remove it $xml =~ s[^\s+",\s+$][]mg; # find out how many opening braces are in the string my $count = split /{/, $xml; # close all the hashes $xml .= " } " x $count; # complete the transformation with the var declaration and the top-lev +el opening brace my $var = "\$mytable = { " . $xml; # After print "After the transformation: \n"; print "$var\n"; # define the lexical that our transformed text will be eval'ed into my $mytable; eval $var; # choke if an error occurs in the eval die "ERROR: ", $@, "\n" if $@; # load Data::Dumper to examine the resulting data structure use Data::Dumper qw(Dumper); # the whole hash of hashes (and plain text values) print "\nThe whole object:\n"; print Dumper $mytable; # an example of a nested object print "\nThe Geocode -> result -> address_component object:\n"; print Dumper $$mytable{"GeocodeResponse"}{"result"}{"address_component +"};

      "This example ignores the obviously mangled <?xml ?> line at the top

      I lol'd so hard reading that statement :) It was only an example to show the data format, but I failed on that line completely. Thank-you, reading your reply further as well
Re: recreating an array
by Anonymous Monk on Sep 09, 2011 at 16:18 UTC
    You can always install a CPAN module locally, if your system has a C-compiler on it. And you should do so. XML::Twig is what you need here.