Skip to content

Instantly share code, notes, and snippets.

@dginev
Last active August 29, 2015 14:11
Show Gist options
  • Save dginev/828279d9689417d65a14 to your computer and use it in GitHub Desktop.
Save dginev/828279d9689417d65a14 to your computer and use it in GitHub Desktop.
libxml 2.9.2 ID conflicts
#!/usr/perl/bin -w
use strict;
use warnings;
use XML::LibXML;
my $xml_content = <<EOL;
<?xml version="1.0" encoding="UTF-8"?>
<a xml:id="a">
<b xml:id="b"></b>
</a>
EOL
my $dom = XML::LibXML->load_xml(string => $xml_content, no_blanks => 1);
my $a = $dom->documentElement;
my $b = $a->firstChild;
$b->unbindNode();
my $c = $dom->createElement("c");
$c->setAttributeNS('http://www.w3.org/XML/1998/namespace', 'id', "b");
$a->appendChild($c);
print $dom->toString(1),"\n";
@dginev
Copy link
Author

dginev commented Dec 17, 2014

Feel free to mail it to them, I have my hands full at the moment. I added the appendChild at the end, but the error is raised on the setAttributeNS irrespective of what follows it.

@dginev
Copy link
Author

dginev commented Dec 17, 2014

Btw, completely destroying $b removes the warning:

$b->unbindNode();
undef $b;

But this is not so simple in LaTeXML, since we are reusing $b, in a new and different subtree of its original parent.

I also have the eery memory that explicitly calling undef on a node that was just unbound isn't safe and carelessly doing so quickly results in memory leaks.

@brucemiller
Copy link

I don't think the undef should be unsafe, since the DESTROY should only happen if the refcount goes to 0. If there is another reference, it simply won't get destroyed, and the id wont be cleaned up!

I asked on the xml list, and got some good response from Nick Wellnhofer. Basically he made the same suggestions you did! Namely either set to undef, remove the id. Or, also you could put the node into a new document:

XML::LibXML::Document->new->adoptNode($node)

but that would be expensive.

I'm inclined to think that removing the id is the best approach:

$node->removeAttribute('xml:id');

I believe you tested it, and that got rid of the errors? At least the ones from the place where it was used; I'll have to scan through and find all the places that need that treatment. Should just be a few...

@brucemiller
Copy link

Oh, @dginev, so you get a notice! Ha!

@dginev
Copy link
Author

dginev commented Dec 21, 2014

For some reason it didn't even send me a notice ... Thanks for that, removeAttribute should do the trick, we just need to hunt down all positions where we unbind nodes (that we don't reuse later).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment