Genera documento XML in memoria con JavaScript

Sto lavorando a un’applicazione Web che deve inviare XML a un server back-end. Mi piacerebbe creare un documento XML in-memory sul lato client, ma usando routine di manipolazione XML, invece di accodare innumerevoli stringhe insieme. Spero che jQuery possa darmi una mano.

Diciamo che ho bisogno di generare questo documento XML (giocattolo) con JavaScript:

  John Doe    Alice 80   Bob 90    

Per iniziare, ho bisogno di creare un qualche tipo di object documento XML con la radice “report”. Suppongo che uno di questi dovrebbe essere vicino, ma nessuno di essi funziona correttamente e / o non riesco a capire come utilizzare correttamente l’object:

 function generateDocument1() { var report = $(''); return report; } function generateDocument2() { var report = document.implementation.createDocument(null, "report", null); return new XMLSerializer().serializeToString(report); } function createXmlDocument(string) { var doc; if (window.DOMParser) { parser = new DOMParser(); doc = parser.parseFromString(string, "application/xml"); } else // Internet Explorer { doc = new ActiveXObject("Microsoft.XMLDOM"); doc.async = "false"; doc.loadXML(string); } return doc; } function generateDocument3() { var report = createXmlDocument(''); return report; } 

Ora voglio creare e aggiungere elementi. Come lo faccio? Immagino sia qualcosa del genere:

 function generateReportXml() { // Somehow generate the XML document object with root var report = /*???*/; // Somehow create the XML nodes var submitter = /*???*/; var name = /*???*/; // Somehow append name to submitter, and submitter to report submitter.append(name); /*???*/ report.append(submitter); /*???*/ // ... append the rest of the XML return report; } 

Qualche idea?

Senza considerare se è necessario utilizzare jQuery per creare XML, ecco alcune idee su come potresti farlo:

 // Simple helper function creates a new element from a name, so you don't have to add the brackets etc. $.createElement = function(name) { return $('<'+name+' />'); }; // JQ plugin appends a new element created from 'name' to each matched element. $.fn.appendNewElement = function(name) { this.each(function(i) { $(this).append('<'+name+' />'); }); return this; } /* xml root element - because html() does not include the root element and we want to * include  in the output. There may be a better way to do this. */ var $root = $(''); $root.append ( // one method of adding a basic structure $('').append ( $('').append ( $('').text('John Doe') ) ) // example of our plugin .appendNewElement('students') ); // get a reference to report var $report = $root.find('report'); // get a reference to students var $students = $report.find('students'); // or find students from the $root like this: $root.find('report>students'); // create 'Alice' var $newStudent = $.createElement('student'); // add 'name' element using standard jQuery $newStudent.append($('').text('Alice')); // add 'grade' element using our helper $newStudent.append($.createElement('grade').text('80')); // add 'Alice' to  $students.append($newStudent); // create 'Bob' $newStudent = $.createElement('student'); $newStudent.append($('').text('Bob')); $newStudent.append($.createElement('grade').text('90')); // add 'Bob' to  $students.append($newStudent); // display the markup as text alert($root.html()); 

Produzione:

   John Doe    Alice 80   Bob 90    

Il secondo approccio sembra un buon modo per andare. È stato progettato per funzionare con documenti XML. Una volta creato l’object documento, utilizzare i metodi di manipolazione DOM XML standard per build l’intero documento.

 // creates a Document object with root "" var doc = document.implementation.createDocument(null, "report", null); // create the , , and text node var submitterElement = doc.createElement("submitter"); var nameElement = doc.createElement("name"); var name = doc.createTextNode("John Doe"); // append nodes to parents nameElement.appendChild(name); submitterElement.appendChild(nameElement); // append to document doc.documentElement.appendChild(submitterElement); 

Questo può sembrare un po ‘prolisso ma è il modo giusto per build il documento XML. jQuery non crea alcun documento XML, ma semplicemente fa affidamento sulla proprietà innerHTML per analizzare e ribuild un DOM dato una stringa HTML. Il problema con questo approccio è che quando i nomi dei tag nel tuo XML si scontrano con i nomi dei tag in HTML come

o , i risultati possono essere imprevedibili. (MODIFICA: dal 1.5 c’è jQuery.parseXML () che effettivamente costruisce un documento XML e quindi evita questi problemi – solo per l’analisi).

Per ridurre il formato, scrivi una piccola libreria helper o forse un plugin jQuery per build il documento.

Ecco una soluzione rapida e sporca per la creazione di un documento XML utilizzando un approccio ricorsivo.

 // use this document for creating XML var doc = document.implementation.createDocument(null, null, null); // function that creates the XML structure function Σ() { var node = doc.createElement(arguments[0]), text, child; for(var i = 1; i < arguments.length; i++) { child = arguments[i]; if(typeof child == 'string') { child = doc.createTextNode(child); } node.appendChild(child); } return node; }; // create the XML structure recursively Σ('report', Σ('submitter', Σ('name', 'John Doe') ), Σ('students', Σ('student', Σ('name', 'Alice'), Σ('grade', '80') ), Σ('student', Σ('name', 'Bob'), Σ('grade', '90') ) ) ); 

Ritorna:

 ​John Doe​​Alice​​80​​Bob​​90​ 

vedi esempio

Nota:

 $.createElement = function(name) { return $('<'+name+' />'); }; 

jquery crea elementi in $("") minuscole, $("") e $("") crea elementi uguali

Ho trovato che la funzione di costruzione XMLWriter di Ariel Flesler è un buon inizio per creare XML da zero (in memoria), dai un’occhiata a questo

http://flesler.blogspot.com/2008/03/xmlwriter-for-javascript.html

Esempio

 function test(){ // XMLWriter will use DOMParser or Microsoft.XMLDOM var v = new XMLWriter(); v.writeStartDocument(true); v.writeElementString('test','Hello World'); v.writeAttributeString('foo','bar'); v.writeEndDocument(); console.log( v.flush() ); } 

Risultato

  Hello World 

Un paio di avvertimenti, non sfugge alle stringhe e la syntax può ottenere il coyote ++ brutto.

Hai preso in considerazione JSON? Potresti salvare i dati usando gli oggetti. Quindi potresti usare JSON.stringify(obj); e inviarlo al server.

un semplice esempio

 var obj = new student('Alice',80); function student(a,b){ this.name=a; this.grade=b; } function sendToServer(){ var dataString = JSON.stringify(obj); //the HTTP request }