2017-01-28 5 views
0

Ich habe sowohl einfache als auch komplexe JSON-Daten und es zu XML mit JavaScript-rekursive Methode wie unten Umwandlung:Javascript rekursive String Append

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); 

Diese xml erzeugt völlig in Ordnung, aber ein Problem haben. Hier ist die XML, die es mir gab:

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

Das Problem ist, es hat den ersten Knoten wiederholt. Könnten Sie mir bitte sagen, warum es sich so verhält? Ich habe versucht, eine Menge, es zu debuggen mit dev Werkzeug und ich fand, dass der Cursor direkt Anweisung zurück nach Abschluss dieser Stapel geht:

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

Jede Hilfe sehr geschätzt wird.

Antwort

0

Ersetzen Sie diese Zeile:

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

mit diesem:

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

, da es die XML-Zeichenfolge für die untergeordneten Knoten unabhängig von dem akkumulierten appendTo erstellen hat. Dann hängen Sie das Ergebnis (Rückgabewert) an += an. In Ihrem Code wird das Ergebnis zweimal angehängt (innerhalb der Funktion an appendTo angehängt und dann das bereits angehängte Ergebnis mit += erneut anhängen). Für eine Tiefe von N, das äußere Element wiederholt werden N + 1 mal, das zweite äußere Element wiederholt werden N mal, ... und so weiter, bis das innere Element, das nicht wiederholt wird.

Ein Beispiel für den Fehler, den Sie hatte: appendTo betrachten ist '<outer>' Sie es als Argument für den Funktionsaufruf übergeben, dort appendTo-'<inner>' angehängt wird, wenn der Anruf Ende es '<outer><inner>' zurück, die dann auf den vorherigen Wert, den Sie von appendTo hängen (('<outer>'), +=, so jetzt appendTo wird '<outer><outer><inner>' (das äußere Element wiederholt 2 mal, weil es an den Anruf einmal (eine Ebene unter) übergeben wurde) Wenn es N Ebenen unten waren, dann appendTo wird an den Anruf N übergeben werden Zeiten wie diese:

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

Großen. Es funktioniert gut, aber können Sie es bitte mehr ausarbeiten? wie es funktioniert hat. und was ist das Problem mit meiner Implementierung? –

+0

Ich denke, Sie können nur 'obj' als Eingabeparameter nehmen und' appendTo' in der Funktion deklarieren. –

+0

@ManishJangir Ich habe ein Beispiel hinzugefügt. Nicht 100% genau, aber Sie werden die Idee bekommen. –

0

nur für einige Sorten; du könntest genauso gut tun;

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));