Firefox和Chrome中XMLSerializer的细微差别?

Firefox和Chrome中XMLSerializer的细微差别?,xml,json,google-chrome,firefox,xmlserializer,Xml,Json,Google Chrome,Firefox,Xmlserializer,下面的代码片段使用createDocument和XMLSerializer API将Javascript对象转换为XML字符串。问题是它在Chrome(23.0.1271.101)和Firefox(14.0.1)浏览器上生成不同的输出 var item = { _dto: {...} }; // the 'model' object var xmlDto = $('<Column />'); // this is eventually serialized and sent to t

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

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;
看起来Firefox和Chrome中的XMLSerializer有细微的区别,但我需要验证这一点。在任何情况下,Firefox输出都是无效的XML。有人能解释一下吗

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


如果首先我有一种方法可以序列化为JSON,并且能够保留密钥顺序,我就不会这么做。

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

是的,Firefox输出是有效的XML。是什么让你认为这是无效的


我提交了

我们无法控制XMLSerializer的默认/假设,firefox生成的不是无效文档,而是名称空间处理的实现细节。您可以从“xmlDoc.createElement(“Name”);”切换对于“xmlDoc.createElements(”);”,可以帮助您解决其他人所说的问题,请尝试将
var tag=xmlDoc.createElement(标记名);
更改为
var tag=xmlDoc.createElements(“)http://example.org/v1,标记名)
在您想要的名称空间中包含元素。我认为这不是Chrome中的错误,而是FF的问题。按照XSD规则,一般惯例是默认情况下所有元素的名称空间都是非限定的,只有在需要覆盖父元素名称空间时才会使用CreateElements。这将非常不方便使用每个实例中都有CreateElements。创建元素时没有父元素。因此它只是在空名称空间中创建的。请注意,有人建议改用XHTML名称空间,在这种情况下,元素将最终位于XHTML名称空间中,这可能对您的目的同样有害。我同意这很不方便,但是元素的名称空间是不可变的,因此必须在创建时设置。在任何情况下,创建元素时,两种浏览器都将元素置于空名称空间中。Chrome只是搞砸了序列化。我的服务器是Apache CXF,它拒绝Firefox生成的文档,如示例中所述,使用
createElement
only.Using
createElementNS
在Chrome和Firefox上生成相同的输出,我的服务器能够正确处理。好吧,Firefox生成的文档可能与您的架构不匹配,这就是它被拒绝的原因。但是它是格式良好的XML,并且与序列化的DOM匹配。Chrome文档是格式良好的XMLt与序列化的DOM不匹配,因此最终会出现“两个bug相互抵消”的情况
    <?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>
     <?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>