I think I may just have won this. The last twenty-four hours have been spent trying to trace the wackiest problem I have ever come across. I will write this for Google in case it ever bites anybody else.
I am applying an XSLT sheet to a DOMDocument in PHP. The simplified test case for the bug is an empty stylesheet with just the identity transform and a single
@xml:id (the key is not used anywhere in the stylesheet, only declared). When the sheet is applied, everything works perfectly except for elements with
@xml:lang, which mysteriously hop over to a different namespace.
The bug only occurs when the key is declared, and when the DOMDocument has been built in memory by PHP. Calling
normalizeDocument before applying the stylesheet has no effect (the docs say that this 'has the effect of saving to XML and then reloading'), but if I myself serialize then unserialize back into the same DOMDocument, the bug magically disappears. So, is the reloading changing the DOMDocument? Not in any way that I can tell. Re-serialising the reloaded DOMDocument gives identical XML to the first time, and I have checked all the members of the DOMDocument, which also do not change.
I have wasted a lot of time on this and am thoroughly spooked by it. It is not even clear where to report the bug if it is one. In the short term though, the rule is: if having very weird output using XSLT, try serializing and reloading just in case. PHP 5.3.2-1, libxml2 2.7.7.