Question

Premise: I come from C++ and I'm pretty noob at Perl. I'm trying to add a stylesheet declaration to a given .xml file. The .xml file is created by a third part and downloaded aside; we are not questioning correctness nor well-formedness of the XML. We also can't know if the XML in the file is indented or in one-row.

Not being able to manipulate the file neatly only with Perl, I took XML::LibXML but I'm still stuck. This is so far what I've done.

#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;

my $path = './file.xml';

my $fxml = XML::LibXML::Document->new('1.0','utf-8');
my $pi = $fxml->createPI("xml-stylesheet");
$pi->setData(type=>'text/xsl', href=>'trasf.xsl');
$fxml->appendChild($pi);

$XML::LibXML::skipXMLDeclaration = 1;
my $docwodecl = XML::LibXML::Document->new;
$docwodecl = $doc->toString;

open my $out_fh, '>', $path;
print {$out_fh} $final_xml.$docwodecl;
close $out_fh;

With this I only get the XML without the initial declaration <?xml version="1.0" encoding="ISO-8859-1"?> and the utf-8 characters are all messed up. I've tried to use something like this

$fxml->setDocumentElement($doc);
$fxml->toFile($path);

but it doesn't work. There's some method i could use to accomplish my (after all pretty simple) goal? I've looked in the docs but I can't find anything useful.

EDIT

The stylesheet declaration have to be after the <?xml version="1.0" encoding="UTF-8"?> and before the actual XML.

Was it helpful?

Solution

Change your fxml initialisation to

my $fxml = XML::LibXML->load_xml(location => $path);

You are not loading the original file anywhere.

Update

You can insert the node before the root element by using insertBefore:

my $path = '1.xml';
my $fxml = XML::LibXML->load_xml(location => $path);
my $pi   = $fxml->createPI('xml-stylesheet');
$pi->setData(type => 'text/xsl', href => 'trasf.xsl');
$fxml->insertBefore($pi, $fxml->documentElement);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top