4

So I think there are probably cleaner solutions than what I am doing anyway, but I'm wondering if this is a known issue, if there's something obvious I'm doing wrong, etc...

For reasons not worth describing, I have some Javascript code that, in one possible path, is loading XML from a string using DOMParser, then serializing it back to a string with XMLSerializer. The XML document is an XSL stylesheet. There are two xmlns elements in the main xsl:stylesheet tag: One which declares the xsl namespace, and another which declares a custom namespace that I use. (Call it "foo")

In IE9, at least, when I get the output back from the round trip through DOMParser, the xmlns:xsl element is still there, but the xmlns:foo element is missing. Is this expected behavior? What am I missing?

pnuts
  • 58,317
  • 11
  • 87
  • 139
user435779
  • 413
  • 4
  • 15

2 Answers2

1

I made a test case http://home.arcor.de/martin.honnen/javascript/2012/test2012070901.html and I can confirm that the output with IE 9 on Windows 7 is

Input
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:foo="http://example.com/foo">
<xsl:template match="foo:bar">Test</xsl:template>
</xsl:stylesheet>
Output
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="foo:bar">Test</xsl:template>
</xsl:stylesheet>

so the namespace declaration is dropped. I consider that a bug in IE 9, you might want to check connect.microsoft.com whether anything like that is already reported, and if not file it. Is anyone reading here using IE 10? What does IE 10 show?

[edit]There is a connect issue on IE 10, probably related: https://connect.microsoft.com/IE/feedback/details/728093/xmlserializer-omits-xmlns-attributes.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • What if you actually use the prefix on an element somewhere within the file? Does it drop it then? – Wayne Jul 09 '12 at 18:14
  • 1
    The connect issue suggests that a prefix used in an attribute or element name causes a namespace declarations to be emitted but that does not help if you have attribute values (like `xsl:template match`) containing qualified names. – Martin Honnen Jul 09 '12 at 18:17
  • OK, sorry, I didn't make it beyond the login screen for that connect issue. – Wayne Jul 09 '12 at 18:18
  • Also, that makes sense, right? Whatever's parsing this would have to be aware that the `match` attribute means something specific in the XSLT dialect. – Wayne Jul 09 '12 at 18:20
  • I can't find anything in any XML spec that addresses unused namespaces. – Wayne Jul 09 '12 at 18:31
  • I don't think that ignoring namespace declaration attributes when serializing makes sense in a namespace aware world of XML. If they are in the DOM tree then they should be serialized. And other DOMParser/XMLSerializer implementations in other browsers like Mozilla Firefox, Google Chrome or Opera do so, with IE 9 introducing support for these APIs to be compatible with other browsers it should certainly implement them in a compatible way. There is also some attempt at a spec for these APIs http://html5.org/specs/dom-parsing.html#concept-serialize-xml although it does not look very detailed. – Martin Honnen Jul 10 '12 at 09:54
  • Martin has it nailed... yes, I did not think about the fact that, in an XSLT document, it is a common case to have to declare a namespace despite the fact that you don't actually have any elements that use that namespace (since the namespaces are referenced indirectly by the xsl). IE9 is trying to be cute by stripping out namespaces it presumes are unnecessary, but since it doesn't have semantic knowledge of what the XML is supposed to mean, it can't really do that. I have already re-written my code so that it doesn't deserialize and reserialize the XSL document. Thanks for the answer! – user435779 Jul 11 '12 at 13:50
0

I was also experiencing this issue. In IE11, I had some javascript serializing XML and the namespace URI's were being dropped.

As a workaround I used the createElementNS method when creating the appropriate child node.

So for example, instead of ...

var r = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:n0="web5540"></soap:Envelope>';
var m = new DOMParser().parseFromString(r, "text/xml");
var n = m.createElement('n0:GetSales');
var p = m.firstChild;
p.appendChild(n);
var k = new XMLSerializer().serializeToString(m);
// In IE, k = "<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ><n0:GetSales /></soap:Envelope>"

... I end up doing this ...

var r = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"></soap:Envelope>';
var m = new DOMParser().parseFromString(r, "text/xml");
var n = m.createElementNS('web5540', 'n0:GetSales');
var p = m.firstChild;
p.appendChild(n);
var k = new XMLSerializer().serializeToString(m);
// In IE, k = "<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><n0:GetSales xmlns:n0="web5540" /></soap:Envelope>"

I am not sure this would help in the original case, as the DOMParser would be doing all of the element creation, but I decide to post in case someone else is having a similar issue.

Ryan P
  • 128
  • 1
  • 8