When I am splitting the key to lat long, it gets split with the
number, not the decimal part.
I'm not the best one to help with XML stuff, but I can perhaps offer
help on this. I think the best approach is not to split away
what you do not want, but to extract what you do want, real numbers in
this case. The Regexp::Common module is useful in this, for it
defines a real-number pattern.
Win8 Strawberry 5.30.3.1 (64) Tue 01/12/2021 14:15:24
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
# pm#11126809
use Regexp::Common qw(number);
my $rx_lat_lon = qr{ (?<! \d) $RE{num}{real} (?! \d) }xms;
for my $lat_lon (
'123,456', '12.345, -0', ' -2. , 0.987', ' -.0 ,0.987 ',
'0, -0', '.0 ,-.0', '0. , -0.', ' 0.0 , -0.0 ',
'1, -1', '.1 ,-.1', '1. , -1.', ' 1.2 , -1.2 ',
'123 456', '123', 'foo', '123,foo', 'foo,123', '1.234.5',
) {
my $got_lat_lon =
my ($lat, $lon) =
$lat_lon =~ m{ \A \s* ($rx_lat_lon) \s* , \s* ($rx_lat_lon) \s* \z
+ }xms;
# $lat_lon =~ m{ $rx_lat_lon }xmsg; # no data validation
if ($got_lat_lon) {
printf "%18s -> lat %-10s lon %-10s \n",
"'$lat_lon'", n_or_undef($lat), n_or_undef($lon);
}
else {
print "'$lat_lon' FAILED to extract lat/lon \n";
}
}
sub n_or_undef { return defined $_[0] ? "'$_[0]'" : 'undef'; }
^Z
'123,456' -> lat '123' lon '456'
'12.345, -0' -> lat '12.345' lon '-0'
' -2. , 0.987' -> lat '-2.' lon '0.987'
' -.0 ,0.987 ' -> lat '-.0' lon '0.987'
'0, -0' -> lat '0' lon '-0'
'.0 ,-.0' -> lat '.0' lon '-.0'
'0. , -0.' -> lat '0.' lon '-0.'
' 0.0 , -0.0 ' -> lat '0.0' lon '-0.0'
'1, -1' -> lat '1' lon '-1'
'.1 ,-.1' -> lat '.1' lon '-.1'
'1. , -1.' -> lat '1.' lon '-1.'
' 1.2 , -1.2 ' -> lat '1.2' lon '-1.2'
'123 456' FAILED to extract lat/lon
'123' FAILED to extract lat/lon
'foo' FAILED to extract lat/lon
'123,foo' FAILED to extract lat/lon
'foo,123' FAILED to extract lat/lon
'1.234.5' FAILED to extract lat/lon
(I haven't tested it, but I think this code will work under
virtually any Perl version. (Update: Counter-examples
are welcome!))
Some comments:
-
The $RE{num}{real} pattern is not bounded (by design!), so defining
an explicit $rx_lat_lon bounded pattern with
my $rx_lat_lon = qr{ (?<! \d) $RE{num}{real} (?! \d) }xms;
is IMHO good practice and gives you a single point at which to
change the definition of a lat/lon value should this become
necessary.
-
Defining an explicit pattern for matching a lat/lon field with
m{ \A \s* ($rx_lat_lon) \s* , \s* ($rx_lat_lon) \s* \z }xms
is again good practice IMHO because it can provide for a high degree
of data validation. The $got_lat_lon flag is true if valid
data is extracted.
-
If you are certain there will always be exactly two lat/lon
sub-fields present and you don't care what else is there, you can
use the simpler
m{ $rx_lat_lon }xmsg
matching expression (note the /g modifier). The $got_lat_lon
flag becomes almost meaningless in this case.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
my @lat_lon_key = (split /[.]/, $key);
my $lat_key = join('.', @lat_lon_key[0,1]);
my $lon_key = join('.', @lat_lon_key[2,3]);
$VAR1 = {
'53.58964145.8.560993391' => {
'name' => 'A99_984_KEI',
'id' => '-1643796'
},
'53.58464146.8.560693392' => {
'id' => -1643795,
'name' => 'A88_984_KEI'
}
};
In the above Hash, if the 1st Hash key is present in the XML then it gets updated but if the 2nd Hash key is not present or rejected then it should get added as new tag in XML.
Now my problem is I am not getting the desired rejected HoH keys in my else part of the statement. What I have to do in else part to get the rejected HoH key and build a new node in XML with it?
| [reply] [d/l] [select] |
#!/usr/bin/env perl
use strict;
use warnings;
my @nodes = qw/foo quux baz/;
my %HoH = (
foo => { day => 'Mon' },
bar => { day => 'Tue' },
baz => { day => 'Wed' }
);
# Loop over nodes
for my $node (@nodes) {
if (exists $HoH{$node}) {
print "Node $node found in HoH and deleted\n";
# Do more processing here
delete $HoH{$node};
} else {
print "Node $node not found in HoH\n";
}
}
# Loop over remaining unmatched keys
for my $key (keys %HoH) {
print "Key $key with payload $HoH{$key}->{day} not matched, so add
+ed\n";
}
| [reply] [d/l] |