0

Simple question:

use warnings;
use XML::Simple;
use Data::Dumper;

my $file='test.osm';

my $test_data = XMLin( $file ); 

print Dumper( $test_data ); 

my @way_node_refs=$test_data->{'way'}->{'nd'};

print Dumper( @way_node_refs ); 

print( @way_node_refs[1]->{'ref'} );ere

It has the following output. The first dump is not given because it does not matter.

$VAR1 = [
      {
        'ref' => '453966480'
      },
      {
        'ref' => '453966490'
      },
      {
        'ref' => '453966482'
      },
      {
        'ref' => '453966130'
      },
      {
        'ref' => '453966143'
      },
      {
        'ref' => '453966480'
      }
    ];

How can I access the values with the key ref. I don't know how to interprete the braces kinda.

Drav Sloan
  • 1,562
  • 9
  • 13
mad_a_i
  • 23
  • 1
  • 5
  • its an array of annonmous hashes so you will need to access it as such with something like `$myarray->{'ref'}` or to print them all on a new line `print "$_->{'ref'}\n" foreach (@myarray);` – Chris Doyle Aug 16 '16 at 10:01
  • Also this `print( @way_node_refs[1]->{'ref'} );` should be `print( $way_node_refs[1]->{'ref'} );` when accessing an arrays nidex the syntax uses the $ sigil – Chris Doyle Aug 16 '16 at 10:04
  • Don't use XML::Simple. [Its documentation discourages using it](https://metacpan.org/pod/XML::Simple#STATUS-OF-THIS-MODULE). If you know what you want to do with the data in your XML file, you can use XML::Twig or XML::LibXML instead to write easier to maintain code that is more terse and less error-prone. – simbabque Aug 16 '16 at 10:06
  • If you post the source XML, we can give you a MUCH better solution, that doesn't use `XML::Simple`. – Sobrique Aug 16 '16 at 10:27
  • http://wiki.openstreetmap.org/wiki/OpenLayers_osm_file_example – mad_a_i Aug 16 '16 at 11:12
  • 1
    It's best if you post a new question asking how you can get to the specific values you want from that input without using XML::Simple. – simbabque Aug 16 '16 at 11:21
  • I don't want to overdo it simbaque because the implementation in perl is just a prototype. The whole thing will be done in C later on. – mad_a_i Aug 16 '16 at 13:54

2 Answers2

3

This is called array of hashes. If $array contains the data then below will work :

[] is anonymous array reference, while {} is anonymous hash reference. Check perlref.

for (@{ $array }) {
    print $_ -> {ref},"\n";
}

Further reading:

  1. Using Arrow operator(->) - Most suitable for accesing a single item from arrayref or hashref.
  2. Using @ { } - Suitable for iterating over arrayrefs .

Edit:

Now after your edit, it is clear that you want something like this:

for (@way_node_refs) {
    print $_ -> {ref},"\n";
}
Arunesh Singh
  • 3,489
  • 18
  • 26
2

You have an array reference where the values inside the array are hash references. To access single values, use the arrow operator ->.

 print $foo->[0]->{ref};
 print $foo->[1]->{ref};

Or you can loop through them.

foreach my $elem ( @{ $foo } ) {
    print Dumper $elem;
    print $elem->{ref};
}

You could even sort them alphabetically by the values of the ref keys.

my @sorted = sort { $a->{ref} cmp $b->{ref} } @$foo; # note @sorted is an array

See perlref, perlreftut and perldsc for more details on data structures and references.

simbabque
  • 53,749
  • 8
  • 73
  • 136