Reputation: 23
I am new to perl, so please excuse my naivety.
I have a few thousand XML files and their corresponding older versions, for each in each of which I need to read one value (Movie -> Weight) from the old XML file and update it to the new XML file, ideally keeping the same filename.
Files, partly look like this.
# Old XML file
<?xml version="1.0" encoding="UTF-16"?>
-<Movie MagnificationCorrection="1, 1, 0" Weight="1" Bfactor="0" MaskPercentage="1.5895931142410015649452269200" MeanFrameMovement="0.8939736" CTFResolutionEstimate="3.1" UnselectManual="null" UnselectFilter="False">
</Movie>
# new XML file
<?xml version="1.0" encoding="UTF-16"?>
-<Movie MagnificationCorrection="1, 1, 0" Weight="3" Bfactor="0" MaskPercentage="1.5895931142410015649452269200" MeanFrameMovement="0.3284904" TFResolutionEstimate="3.1" UnselectManual="null" UnselectFilter="False">
</Movie>
My approach was rather crude: I parsed the old file using XML::LibXML and extacted the old value,
use warnings;
use XML::LibXML;
my $olddom = XML::LibXML -> load_xml(location => "oldfile.xml");
my $oldWeight = $olddom -> findnodes('//movie/@Weight');
and then tried opening the new XML file in write mode and old file in read mode so that I would copy and print every row from the old file to the new unless the row happens to have the keyword " Weight=", in which case it would edit the row to contain the old weight value and then print the row in the new file.
#Apologies for how crude the code looks.
open (my $oldfh,"<oldfile.xml") or die "Not found\n";
open (my $newfh, ">newfile.xml") or die "Error\n";
my $matchstring = ' Weight=';
while (my $row = <$oldfh>){
my $match = 0;
my @row_comp = split(/"/,$row);
foreach my $row_comp(@row_comp){
if ($row_comp eq $matchstring){
my $match = 1;
}
}
if $match == 1{
my $newrow = @row_comp[0];
foreach (1..16){
if $_ == 2{
$newrow = $newrow . "\"" . $oldWeight;
}else{
$newrow = $newrow . "\"". @row_comp[$_]);
}
}
}else{
print $newfh $row;
{
}
}
However, ($row_comp eq $matchstring)
never gives me "True" value even though I checked the values to be equal by printing them. Could it be because of encoding? If so, how can I fix it? I am sure there are more elegant ways to achieve what I am trying; I figured this would be a quick and dirty way to solve my problem (evidently not). I would greatly appreciate any suggestions.
Upvotes: 2
Views: 261
Reputation: 241858
I'd use XML::LibXML to change the value, too.
#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;
my $olddom = 'XML::LibXML'->load_xml(location => 'old.xml');
my $oldweight = ($olddom->findnodes('//Movie/@Weight'))[0]->value;
my $newdom = 'XML::LibXML'->load_xml(location => 'new.xml');
my $newweight = ($newdom->findnodes('//Movie/@Weight'))[0];
$newweight->setValue($oldweight);
$newdom->toFile('new2.xml');
Upvotes: 4