#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Text::CSV_XS; use XML::LibXML; my %name; my $csv = 'Text::CSV_XS'->new({allow_whitespace => 1, auto_diag => 1, binary => 1}); open my $in, '<:encoding(UTF-8)', 'test.csv' or die $!; $csv->header($in); while (my $row = $csv->getline($in)) { $name{$row->[0]}{$row->[1]} = $row->[2]; } my $dom = 'XML::LibXML'->load_xml(location => 'test.osm'); for my $node ($dom->findnodes('/osm/node')) { my $tag = $node->findnodes('tag[@k="name"]')->[0]; if (my $name = $name{ $node->{lat} }{ $node->{lon} }) { $tag->{v} = $name; } else { warn "No name found for $tag->{v}: @$node{qw{ lat lon }}\n"; } } $dom->toFile('new.osm');
Or, you can load the XML into a DOM, then read the CSV line by line, searching the DOM for the corresponding node and renaming it:
#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Text::CSV_XS; use XML::LibXML; my $dom = 'XML::LibXML'->load_xml(location => 'test.osm'); my $csv = 'Text::CSV_XS'->new({allow_whitespace => 1, auto_diag => 1, binary => 1}); open my $in, '<:encoding(UTF-8)', 'test.csv' or die $!; $csv->header($in); my $xpath_template = '/osm/node[@lat="%"][@lon="%"]'; while (my $row = $csv->getline($in)) { my $i = 0; my $xpath = $xpath_template =~ s/%/$row->[$i++]/gr; my $node = $dom->findnodes($xpath)->[0]; if ($node) { my $tag = $node->findnodes('tag[@k="name"]')->[0]; $tag->{v} = $row->[2]; } else { warn "@$row missing in XML\n"; } } $dom->toFile('new.osm');
In reply to Re: Update XML Values using two primary keys
by choroba
in thread Update XML Values using two primary keys
by pratikpooja
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |