in reply to Re^3: Update XML Values using two primary keys
in thread Update XML Values using two primary keys

The HoH worked, Thank you. Since the HoH is not sorted so how can we compare the key of hashes with the node latitude and longitude and update the names. For e.g. what should be the condition in the if statement?

my $inputfile = 'test_data.csv'; my $csv = Text::CSV->new ({binary => 1,auto_diag => 1,sep_char =>';'} +); open(my $data, '<:encoding(utf8)', $inputfile) or die "Could not open +'$inputfile' $!\n"; my $header = $csv->getline($data); $csv->column_names($header); my %HoH; while (my $row = $csv->getline_hr($data)) { my $key = "$row->{latitude}.$row->{longitude}"; # Compare next if exists $HoH{$key} && $row->{id} >= $HoH{$key}->{id}; # Set (or overwrite) $HoH{$key} = {name => $row->{name},id => $row->{id}}; } foreach my $key1 (keys %HoH) { print "'$key1'\n"; foreach my $key2 (keys %{$HoH{$key1}}) { print $key2=$HoH{$key1}{$key2},"\n"; } } my $myhash = \%HoH; my $dom = 'XML::LibXML'->load_xml(location => 'test.osm'); for my $node ($dom->findnodes('/osm/node')) { my $tag = $node->findnodes('tag[@k="name"]')->[0]; print $tag,"\n"; if () { } }

Replies are listed 'Best First'.
Re^5: Update XML Values using two primary keys
by hippo (Archbishop) on Jan 11, 2021 at 12:23 UTC

    Just build the key from the lat and lon as before:

    for my $node ($dom->findnodes('/osm/node')) { my $tag = $node->findnodes('tag[@k="name"]')->[0]; print $tag,"\n"; my $key = "$node->{lat}.$node->{lon}"; if (exists $HoH{$key}) { print "Matching key found for $key with id $HoH{$key}->{id}\n" +; # Do something useful with it here } }

    🦛

      Thank you. I am trying to add the rejected HoH to the XML as new nodes in the else part of the statement but I am getting error in forming the new XML with the rejected HoH.

      my $myhash = \%HoH; my $dom = 'XML::LibXML'->load_xml(location => 'test.osm'); for my $node ($dom->findnodes('/osm/node')) { my $tag = $node->findnodes('tag[@k="name"]')->[0]; my $key = "$node->{lat}.$node->{lon}"; if (exists $HoH{$key}){ $tag->{v} = $HoH{$key}->{name}; $node->{id} = $HoH{$key}->{id}; } else { print "$_\n" for keys %HoH; my($lat_key, $lon_key) = split(/./, $, 2); my $new_node = 'XML::LibXML::Element'->new("node"); my $id = 'XML::LibXML::Attr'->new("id",$HoH{$key}->{id}); my $lat = 'XML::LibXML::Attr'->new("lat",$lat_key); my $lon = 'XML::LibXML::Attr'->new("lon",$lon_key); $new_node->setAttribute($id); $new_node->setAttribute($lat); $new_node->setAttribute($lon); my $new_node_child = 'XML::LibXML::Element'->new("tag"); my $k = 'XML::LibXML::Attr'->new("k",'name'); my $v = 'XML::LibXML::Attr'->new("v",$HoH{$key}->{name}); $new_node_child->setAttribute($k); $new_node_child->setAttribute($v); $new_node->addChild($new_node_child); } } $dom->toFile('new_test.osm');

        my($lat_key, $lon_key) = split(/./, $, 2);

        The first argument to split is a regular expression in which the dot is a metacharacter and should be escaped. Note that since both lat and lon also contain a dot perhaps some other separator character would be a better choice if you want to split the keys. A comma would do and would not need to be escaped.

        but I am getting error

        You've chosen not to share the precise text of the error message. I cannot imagine why.


        🦛

        my($lat_key, $lon_key) = split(/./, $, 2);

        In addition to hippo's comment, note that the quoted extract from this does not compile. While there is a $, Perl special variable (see perlvar), you don't seem to be using it (nor would I recommend doing so in this application). I suspect this is just a cut/paste error and not the error your code is actually producing, but again, who knows?

        Win8 Strawberry 5.8.9.5 (32) Mon 01/11/2021 18:12:15 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings $, = 'foo.bar'; my($lat_key, $lon_key) = split(/\./, $, 2); Number found where operator expected at - line 3, near "$, 2" (Missing operator before 2?) ^Z syntax error at - line 3, near "$, 2" Execution of - aborted due to compilation errors.


        Give a man a fish:  <%-{-{-{-<