Bug adding namespaced attributes

Just a warning, because it caught me out: there's an important bug fix in libxml2 version 2.6.26. If you're writing Perl code which produces XML with namespaced attributes (in my case OpenDocument files) then it'll bite you if you try to run the code on an older libxml library.

The problem is that if you add an attribute (with setAttribute) with a name which includes a namespace prefix, and the element you're adding it to doesn't yet have an appropriate namespace declaration (because you've put the xmlns:foo on the root element, and your new element hasn't been added to that yet), then the attribute simply won't be added.

After being puzzled that styling was missing from my documents when I generated them on a friend's machine, I figured it out and wrote a little test script just to make sure I knew what was going on:

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

my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my $root =  $doc->createElement('root');
$root->setNamespace(foo => 'http://example.com/', 0);
$doc->setDocumentElement($root);

my $child = $doc->createElement('child');
$child->setAttribute('foo:bar' => 'attribute value');
$root->appendChild($child);

print $doc->toString(1);

With libxml2 version 2.6.26 I get this, which is right:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:http://example.com/="foo">
  <child foo:bar="attribute value"/>
</root>

This is what you get with libxml2 version 2.6.24:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:http://example.com/="foo">
  <child/>
</root>

< Character encodings in Perl | Nasty bug in TT 2.14 >