My XML file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:element name="foo">
<xsl:value-of select="bar"/>
</xsl:element>
</xsl:stylesheet>
I'm using XML:LibXML::Reader and trying to perform logic on each node when certain criteria are meet. For example:
<xsl:element name="foo">
output:
<xsl:element name="foobar">
Here is what I currently have:
use strict;
use warnings;
use XML::LibXML::Reader;
my $reader = XML::LibXML::Reader->new(location => "test.xml") or die "cannot read input file\n";
while ($reader->read){
processNode($reader);
}
sub processNode{
my $reader = shift;
printf "%s\n", ($reader->name);
}
My output looks like this:
xsl:stylesheet
#text
xsl:element
#text
xsl:value-of
#text
xsl:element
#text
xsl:stylesheet
Ok, the problem here is - you're essentially misunderstanding the tree nature of XML. You've got a bunch of nodes - that 'you're "walking"' but actually the xsl:stylesheet
node is a parent of the xsl:element
node.
By far the easiest way is to not do it the way you are, and instead:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $reader = XML::LibXML->load_xml(location => "test.xml") or die "cannot read input file\n";
print $reader -> toString
But I'm pretty sure your requirement is something slightly more complicated.
Edit: And sure enough, it was.
So - change every 'foo' name to a 'foobar' name:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $reader = XML::LibXML->load_xml(location => "test.xml") or die "cannot read input file\n";
my $xpath_context = XML::LibXML::XPathContext->new($reader);
foreach my $foo_node ( $xpath_context -> findnodes('//xsl:element[@name="foo"]') ) {
$foo_node -> setAttribute ( 'name', 'foobar' );
}
print $reader -> toString