2013-01-09 135 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上生成相同的輸出。 –