2013-01-09 132 views
1

以下代码片段使用createDocument和XMLSerializer API将Javascript对象转换为XML字符串。问题在于它在Chrome(23.0.1271.101)和Firefox(14.0.1)浏览器上生成不同的输出。Firefox和Chrome中XMLSerializer的细微差别?

var item = { _dto: {...} }; // the 'model' object 
var xmlDto = $('<Column />'); // this is eventually serialized and sent to the server 
var optionalTags = ['Abstract', 'Note', 'Size', 'Digits', 'Nullable', 'AutoUpdate', 'DataType']; 

// convert badgerfish JSON back to XML. 
// use XML because it is not possible serialize JSON and preserve key order. 
var xmlDoc = document.implementation.createDocument("http://example.org/v1", "Column", null); 
var root = xmlDoc.childNodes[0]; 
var nameTag = xmlDoc.createElement("Name"); 
nameTag.setAttribute('uuid', item._dto['Name']['@uuid']); 
nameTag.textContent=item._dto['Name']['$']; 
root.appendChild(nameTag); 
optionalTags.map(function (tagName) { 
    var tag = xmlDoc.createElement(tagName); 
    tag.textContent=item._dto[tagName]; 
    if (item._dto.hasOwnProperty(tagName)) { 
     tag.textContent=item._dto[tagName]; 
     root.appendChild(tag); 
    } 
}); 

var xmlStr = new XMLSerializer().serializeToString(xmlDoc); 
xmlStr = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+xmlStr; 

在Chrome,生成以下期望/预期输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <Column xmlns="http://example.org/v1"> 
      <Name uuid="001b5cbe-bab7-4880-90b6-9e8f47f6e4af">FAILED_ID</Name> 
      <Size>38</Size> 
      <Digits>0</Digits> 
      <Nullable>true</Nullable> 
      <AutoUpdate>false</AutoUpdate> 
      <DataType>NUMERIC</DataType> 
    </Column> 

但在Firefox,所产生的输出具有xmlns属性插入在每一个标签具有空值:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <Column xmlns="http://example.org/v1"> 
      <Name xmlns="" uuid="001b5cbe-bab7-4880-90b6-9e8f47f6e4af">FAILED_ID</Name> 
      <Size xmlns="">38</Size> 
      <Digits xmlns="">0</Digits> 
      <Nullable xmlns="">true</Nullable> 
      <AutoUpdate xmlns="">false</AutoUpdate> 
      <DataType xmlns="">NUMERIC</DataType> 
    </Column> 

它看起来像在XMLSerializer的Firefox和Chrome有细微的差别,但我需要验证这一点。无论如何,Firefox输出都是无效的XML。有人可以对此有所了解吗?

是否有更好的方法来生成在浏览器的XML文档?

如果在第一个地方,我不会做这个,我有办法序列化JSON与保留键顺序的能力。

+0

没有太多我们可以做控制的XMLSerializer的默认/假设和Firefox产生什么不是无效的文档,但命名空间处理的实施细则。您可以从'xmlDoc.createElement(“Name”);'到'xmlDoc.createElementNS(“http://example.org/v1”,“Name”); '这会帮助你解决问题 – Baski

+0

正如其他人所说,尝试改变'var标记= xmlDoc.createElement(标签名);''来var标记= xmlDoc.createElementNS(' http://example.org/v1' , tagName);'在你想要的命名空间中拥有这些元素。 – JLRishe

回答

3

Firefox的序列化是正确的。当您创建这些元素与createElement,不createElementNS,这使他们在空命名空间(您可以通过检查元素的namespaceURI在创建后检查)。但是,解析Chrome生成的序列化会将它们放入http://example.org/v1命名空间。

是的,Firefox的输出是有效的XML。是什么让你觉得这是无效的?

我申请https://bugs.webkit.org/show_bug.cgi?id=106531

+0

IMO我不认为这是Chrome中的错误,而是FF的问题。一般约定,如果按照XSD规则进行操作,则所有元素都是默认名称空间,并且只有在需要覆盖父元素名称空间时才会使用createElementNS。在每个实例中使用createElementNS会非常不方便。 – Baski

+0

当你创建一个元素时,没有父元素。所以它只是在空名称空间中创建的。请注意,有人建议使用XHTML名称空间,在这种情况下,您的元素最终会在XHTML名称空间中使用,这大概与您的目的一样糟糕。我同意这很不方便,但是元素的名称空间是不可变的,所以必须在创建时设置。无论如何,两个浏览器在创建它们时都会将这些元素放入空名称空间中。 Chrome只是把它串起来。 –

+0

我的服务器是Apache CXF,它仅使用'createElement'来拒绝由Firefox生成的文档。 使用'createElementNS'可以在我的服务器能够正确处理的Chrome和Firefox上生成相同的输出。 –