Как мне отредактировать содержимое файла XML в perl? - PullRequest
2 голосов
/ 26 января 2020

Я новичок в perl, поэтому прошу прощения за мою наивность.

У меня есть несколько тысяч XML файлов и соответствующих им более старых версий, для каждого из которых мне нужно прочитать одно значение (Mov ie -> Weight) из старого файла XML и обновите его до нового файла XML, в идеале сохраняя то же имя файла.

Файлы, отчасти выглядят так.

# 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>

Мой подход был довольно грубым: я проанализировал старый файл с помощью XML :: Lib XML и извлек старое значение

use warnings;
use XML::LibXML;

my $olddom = XML::LibXML -> load_xml(location => "oldfile.xml");

my $oldWeight = $olddom -> findnodes('//movie/@Weight');

, а затем попытался открыть новый XML файл в режиме записи и старый файл в режиме чтения, чтобы я мог копировать и печатать каждую строку из старого файла в новый, если в строке не было ключевого слова "Weight =", и в этом случае он будет редактировать строку чтобы содержать старое значение веса, а затем распечатать строку в новом файле.

#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;
    {
    }       
}

Однако ($row_comp eq $matchstring) никогда не дает мне «Истинное» значение, даже если я проверил, чтобы значения были равны, печатая их. Может ли это быть из-за кодировки? Если так, как я могу это исправить? Я уверен, что есть более изящные способы достигнуть того, что я пытаюсь; Я подумал, что это будет быстрый и грязный способ решить мою проблему (очевидно, нет). Буду очень признателен за любые предложения.

1 Ответ

4 голосов
/ 26 января 2020

Я бы использовал XML :: Lib XML, чтобы изменить значение тоже.

#!/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');
...