'Update xml file containing namespace prefix with XML::Twig

I have the following information in an xml file I need to amend:

<?xml version="1.0" encoding="utf-8"?>
<x:workbook xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" 
            xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <x:workbookPr codeName="ThisWorkbook"/>
    <x:bookViews>
        <x:workbookView firstSheet="0" activeTab="0"/>
    </x:bookViews>
    <x:sheets>
        <x:sheet name="Sheet1" sheetId="2" r:id="rId2"/>
    </x:sheets>
    <x:definedNames/>
    <x:calcPr calcId="125725"/>
</x:workbook>

In general, the prefix "x:" can be anything, including the empty prefix.

I now need to add a child element "x:sheet" to the "x:sheets" element in the file. However, if the file contents had no prefixes then I would need to add a child element "sheet" to the "sheets" element in the file.

Since the prefix, in general, can be anything I use the following perl code to scan and amend the file.

use strict;
use warnings;
use XML::Twig;

my $fileName1='/folder1/file1.xml';
my $fh1;
my $fh1_filename='/folder1/file1_NEW.xml';
my $tw1=new XML::Twig(
map_xmlns => {
    'http://schemas.openxmlformats.org/officeDocument/2006/relationships' => 'r',
    'http://schemas.openxmlformats.org/spreadsheetml/2006/main' => 's'      
},
keep_original_prefix => 1,
pretty_print => 'indented',
twig_handlers => {'/s:workbook/s:sheets' => sub{Add_Sheet_1(@_)}}
);
$tw1->parsefile($fileName1);
open($fh1, '>:encoding(UTF-8)', $fh1_filename);
$tw1->flush($fh1);
close $fh1;
}   
#
#
#
sub Add_Sheet_1{
    my ( $twig, $tag) = @_;
    my $var1='x:sheet';
    $tag->insert_new_elt( 'last_child', => $var1=>{name=>'Sheet_N1',sheetId=>'200'});
}

For the case where the prefix is "x:" this code generates the desired result.

However, in general, the prefix is unknown. My handler maps the unknown prefix to the prefix "s:" So finding the correct element poses no problem.

However, I cannot find any way of adding a new child element with the correct prefix.

Is there any way I can get the original prefix from the file and use it when adding my new child element?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source