I've read some others topics here but this doesn't fit to my sample. I have an XML file where I want to find and replace specific values.
My script is working with expecting result, but it's quite ugly because I don't use all reassources from the module.
I've tried with $node->setData($content);
and $dom->toFile($filename)
but without successful.
Question:
The goal is to find the id from the Media (line 29 column 20 from the XML sample) in order to replace it by $mediaIdFrom
with a better way using the module without open/close files.
Here the script:
#!/usr/bin/perl
use strict;
use warnings 'all';
use autodie;
use feature 'say';
use XML::LibXML;
my $mediaIdFrom = "MEDIAID_TEST";
my $VodItemIdFrom = "VODITEM_ID_TEST";
my $filename = 'sample.xml';
my $out_filename = $filename . ".new";
my $dom = XML::LibXML -> load_xml(location => $filename);
my $mediaId = join '', map { $_->{id}; } $dom->findnodes('/ScheduleProvider/Episode/Media');
my $vodItemId = join '', map { $_->{id}; } $dom->findnodes('/ScheduleProvider/VodItem');
if (-e $filename) {
open(IN, "<", $filename);
open(OUT, ">", $out_filename);
while (<IN>) {
chomp;
$_ =~ s/\"$mediaId\"/\"$mediaIdFrom\"/g if /$mediaId/;
$_ =~ s/\"$vodItemId\"/\"$VodItemIdFrom\"/g if /$vodItemId/;
say $_;
say OUT $_;
}
close(IN);
close(OUT);
}
Here the sample:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ScheduleProvider id="TST" name="SHOP" scheduleDate="2018-07-05T23:05:45Z">
<Product action="override" endPurchase="2018-08-04T21:59:00Z" endValidity="2018-09-05T03:31:00Z" id="TSTP937279650001" regions="Country" rentalDuration="2611920" startPurchase="2018-07-05T16:27:00Z" startValidity="2018-07-05T16:27:00Z" type="single">
<Price currency="EUR" startPurchase="2018-07-05T16:27:00Z" endPurchase="2018-08-04T21:59:00Z">0.00</Price>
<EpgDescription locale="fr_FR">
<EpgElement key="Title">NO TITLE</EpgElement>
</EpgDescription>
</Product>
<Series id="TST903350550001" action="override" title="Seasons - S1">
<EpgDescription locale="fr_FR">
<EpgElement key="Title">Seasons - S1</EpgElement>
<EpgElement key="Synopsis">Smart</EpgElement>
<EpgElement key="ShortTitle">Seasons - S1</EpgElement>
</EpgDescription>
<EpgDescription>
<EpgElement key="Aspect">16:9</EpgElement>
<EpgElement key="PromoImage">TST_ANT_1192194.jpg</EpgElement>
</EpgDescription>
</Series>
<Episode action="override" duration="1080" id="TST937279650001" title="Épisode 9" number="9" episodeList="9" seriesRef="TST903350550001">
<EpgDescription locale="fr_FR">
<EpgElement key="Title">Épisode 9</EpgElement>
<EpgElement key="Synopsis">George</EpgElement>
</EpgDescription>
<EpgDescription>
<EpgElement key="Aspect">16:9</EpgElement>
<EpgElement key="PromoImage">TST_ANT_1192194.jpg</EpgElement>
</EpgDescription>
<Media id="TSTM937279650001" fileName="TSTM937279650001.ts" frameDuration="27000" fileSize="477380316"/>
</Episode>
<VodItem action="override" contentRef="TST937279650001" id="TSTV937279650001" nodeRefs="TSTFRA1001" previewDate="2016-01-05T16:27:00Z" productRefs="TSTP937279650001" title="Épisode 9" broadcasterId="TST">
<EpgDescription>
<EpgElement key="Studio">Replay</EpgElement>
</EpgDescription>
<EpgDescription locale="fr_FR">
<EpgElement key="Title">Épisode 9</EpgElement>
<EpgElement key="Synopsis">George</EpgElement>
</EpgDescription>
<Period start="2018-07-05T16:27:00Z" end="2018-08-04T21:59:00Z"/>
</VodItem>
</ScheduleProvider>
This will do what you want. You just needed to call setAttributes
on the elements that you had located with findnodes
use strict;
use warnings 'all';
use XML::LibXML;
my $filename = 'sample.xml';
my $out_filename = "$filename.new";
my $media_id_from = 'MEDIAID_TEST';
my $vod_item_id_from = 'VODITEM_ID_TEST';
my $doc = XML::LibXML->load_xml(location => $filename);
my ($media) = $doc->findnodes('/ScheduleProvider/Episode/Media');
$media->setAttribute(id => $media_id_from);
my ($vod_item) = $doc->findnodes('/ScheduleProvider/VodItem');
$vod_item->setAttribute(id => $vod_item_id_from);
$doc->toFile($out_filename);