2017-01-28 59 views
0

我有簡單和複雜的JSON數據,並將其與類似下面的JavaScript遞歸方法轉換成XML:的Javascript遞歸字符串附加

var json = [ 
    { 
    "id": "42cfb980-4221-e97f-f85a-f5fcf4d37f02", 
    "name": "outer", 
    "value": "", 
    "attributes": {}, 
    "subNodes": [ 
     { 
     "id": "d0794639-5568-3728-11a4-676eb100b07a", 
     "name": "inner", 
     "value": "inner vlaue", 
     "attributes": {}, 
     "subNodes": [] 
     } 
    ] 
    } 
]; 

function prepareXmlOutput(appendTo, obj) { 
     var i, k, attributeString = ''; 

     for (i in obj) { 
      if (obj[i].attributes.length > 0) { 
       for (k in obj[i].attributes) { 
        attributeString += ((obj[i].attributes[k].name != '') ? obj[i].attributes[k].name+'="'+obj[i].attributes[k].value+'"' : '') + ' '; 
       } 
      } 
      if (obj[i].subNodes.length < 1) { 
       if (obj[i].value == '') { 
        appendTo += '</' + obj[i].name + attributeString.replace(/~+$/,'') + '>'; 
       } else { 
        appendTo += '<' + obj[i].name + attributeString.replace(/~+$/,'') + '>' +obj[i].value+ '</' + obj[i].name + '>'; 
       } 

      } else { 
       appendTo += '<' + obj[i].name + attributeString.replace(/~+$/,'') + '>'; 

       appendTo += prepareXmlOutput(appendTo, obj[i].subNodes); 

       appendTo += '</' + obj[i].name + '>'; 
      } 
     } 
     return appendTo; 
    } 

prepareXmlOutput('', json); 

這將產生XML完全正常,但有一個問題。這是它給我的XML:

"<outer><outer><inner>inner vlaue</inner></outer>" 

問題是,它有第一個節點重複。你能告訴我爲什麼它的行爲如此。我嘗試了很多與開發工具來調試它,我發現光標直接進入完成這個棧後返回聲明:

appendTo += prepareXmlOutput(appendTo, obj[i].subNodes); 

任何幫助表示讚賞。

回答

0

替換此行:

appendTo += prepareXmlOutput(appendTo, obj[i].subNodes); 

與此:

appendTo += prepareXmlOutput('', obj[i].subNodes); 

,因爲它必須從累積appendTo獨立創建的子節點的XML字符串。然後使用+=將結果(返回的值)附加到它。在您的代碼中,結果會附加兩次(在函數內部附加appendTo,然後返回使用+=再次附加的已附加結果)。對於深度N,外部元素重複得到N + 1次,第二個外部元素重複得到N次......等等,直到內部元素不被重複。

你有錯誤的一個例子:考慮appendTo'<outer>'你把它作爲參數傳遞給函數調用,還有appendTo當通話結束就返回'<outer><inner>'你追加到的appendTo以前的值,然後被追加到'<inner>'(這是'<outer>')使用+=,所以現在appendTo變成'<outer><outer><inner>'(外部元素重複2次,因爲它已傳遞給調用一次(下一級))如果有N個級別以下,則appendTo將傳遞給調用N時間是這樣的:

  • 通行證N°1:appendTo = '<outer>'
  • 通行證N°2:appendTo = '<outer><outer><inner>'
  • 通行證N°3:appendTo = '<outer><outer><outer><inner><inner>'
  • ...
+0

大。它工作正常,但您能否詳細闡述它?它是如何工作的。和我的實現有什麼問題? –

+0

我想你可以只將'obj'作爲輸入參數,並在函數內聲明'appendTo'。 –

+0

@ManishJangir我加了一個例子。不是100%準確,但你會明白。 –

0

只爲某些品種;你也可以這樣做;

var json = [ 
 
    { 
 
    "id": "42cfb980-4221-e97f-f85a-f5fcf4d37f02", 
 
    "name": "outer", 
 
    "value": "", 
 
    "attributes": {}, 
 
    "subNodes": [ 
 
     { 
 
     "id": "d0794639-5568-3728-11a4-676eb100b07a", 
 
     "name": "in01", 
 
     "value": "inner value", 
 
     "attributes": {color:"red"}, 
 
     "subNodes": [{ 
 
         "id": "d0794639-5568-3728-11a4-676eb100b07a", 
 
         "name": "in02", 
 
         "value": "more inner value", 
 
         "attributes": {color:"blue"}, 
 
         "subNodes": [{ 
 
             "id": "d0794639-5568-3728-11a4-676eb100b07a", 
 
             "name": "in03", 
 
             "value": "most innest value", 
 
             "attributes": {color:"pink"}, 
 
             "subNodes": [] 
 
            }] 
 
        }] 
 
     }, 
 
     { 
 
     "id": "d0794639-5568-3728-11a4-676eb100b07b", 
 
     "name": "in11", 
 
     "value": "another inner value", 
 
     "attributes": {color:"orange"}, 
 
     "subNodes": [{ 
 
         "id": "d0794639-5568-3728-11a4-676eb100b07a", 
 
         "name": "in12", 
 
         "value": "more inner value", 
 
         "attributes": {color:"brown"}, 
 
         "subNodes": [] 
 
        }] 
 
     } 
 
    ] 
 
    } 
 
], 
 

 
parseXML = (a, r = "") => a.length ? parseXML(a.slice(1), r + Object.keys(a[0].attributes) 
 
                    .reduce((s,k) => s + " " + k + "=\"" + a[0].attributes[k] + "\"", "<" + a[0].name) 
 
                    + ">" 
 
                    + a[0].value 
 
                    + parseXML(a[0].subNodes,"") 
 
                    + "</" 
 
                    + a[0].name 
 
                    + ">") 
 
            : r; 
 
console.log(parseXML(json));