2010-07-07 11 views
33

Ich arbeite an einer Webanwendung, die XML an ein Server-Back-End senden muss. Ich möchte ein XML-Dokument im Speicher auf der Client-Seite erstellen, aber XML-Manipulationsroutinen verwenden, anstatt unzählige Strings zusammenzufügen. Ich hoffe, dass jQuery mir helfen kann.XML-Dokument mit JavaScript im Arbeitsspeicher erstellen

Sagen wir, ich brauche diese (Spielzeug) XML-Dokument mit JavaScript zu generieren:

<report> 
    <submitter> 
     <name>John Doe</name> 
    </submitter> 
    <students> 
     <student> 
      <name>Alice</name> 
      <grade>80</grade> 
     </student> 
     <student> 
      <name>Bob</name> 
      <grade>90</grade> 
     </student> 
    </students> 
</report> 

zu starten, muss ich mit dem „Bericht“ root eine Art von einem XML-Dokument-Objekt erstellen. Ich bin einer von diesen unter der Annahme, sollte in der Nähe sein, aber keiner von ihnen arbeiten ganz richtig, und/oder kann ich nicht ganz herausfinden, wie das Objekt richtig zu nutzen:

function generateDocument1() 
{ 
    var report = $('<report></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('<report></report>'); 

    return report; 
} 

Jetzt will ich erstellen und anhängen Elemente. Wie mache ich das? Ich kann mir vorstellen, dass es so etwas ist:

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

Irgendwelche Ideen?

+0

Stellen Sie sicher, @AlexanderN Lösung am Ende überprüfen, ob Sie ein großes Plugin js Methode wollen Erstellen Sie XML-Strukturen, einschließlich Attribute und CDATA. – whyoz

Antwort

26

Ohne Adressierung, ob Sie sollte jQuery XML zu bauen verwenden, sind hier einige Ideen auf wie Sie könnten es tun:

// 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 <report /> in the output. There may be a better way to do this. 
*/ 
var $root = $('<XMLDocument />'); 

$root.append 
(
    // one method of adding a basic structure 
    $('<report />').append 
    (
     $('<submitter />').append 
     (
      $('<name />').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($('<name />').text('Alice')); 
// add 'grade' element using our helper 
$newStudent.append($.createElement('grade').text('80')); 

// add 'Alice' to <students /> 
$students.append($newStudent); 

// create 'Bob' 
$newStudent = $.createElement('student'); 
$newStudent.append($('<name />').text('Bob')); 
$newStudent.append($.createElement('grade').text('90')); 

// add 'Bob' to <students /> 
$students.append($newStudent); 

// display the markup as text 
alert($root.html()); 

Ausgang:

<report> 
    <submitter> 
     <name>John Doe</name> 
    </submitter> 
    <students> 
     <student> 
      <name>Alice</name> 
      <grade>80</grade> 
     </student> 
     <student> 
      <name>Bob</name> 
      <grade>90</grade> 
     </student> 
    </students> 
</report> 
+4

Ein Problem mit diesem Ansatz besteht darin, dass bei HTML-Tag-Namen die Groß-/Kleinschreibung nicht beachtet wird, während in XML die Groß-/Kleinschreibung beachtet wird. Daher konvertiert jQuery alle Tags in Kleinbuchstaben, was möglicherweise nicht das ist, was Sie wollen. – Jeroen

+1

Gute Warnung "Ohne zu antworten, ob Sie _should_ ...", ließ es mich nachdenken und half – robert4

1

Haben Sie JSON betrachtet ? Sie könnten die Daten mit Objekten speichern. Dann könnten Sie JSON.stringify(obj); verwenden und das an den Server senden.

ein einfaches Beispiel

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 
} 
+0

JSON ist nicht in der Lage, viele Datenstrukturen zu speichern, während XML alles speichern kann. – Dima

60

Der zweite Ansatz scheint einen guten Weg zu gehen. Es wurde entwickelt, um mit XML-Dokumenten zu arbeiten. Nachdem Sie das Dokumentobjekt erstellt haben, verwenden Sie die standardmäßigen XML-DOM-Bearbeitungsmethoden, um das gesamte Dokument zu erstellen.

Dies mag ein wenig wortreich erscheinen, aber ist der richtige Weg, um das XML-Dokument zu erstellen. jQuery erstellt kein XML-Dokument, sondern basiert lediglich auf der innerHTML-Eigenschaft, um ein DOM bei einer gegebenen HTML-Zeichenfolge zu analysieren und zu rekonstruieren. Das Problem bei diesem Ansatz besteht darin, dass bei der Kollision von Tag-Namen in Ihrem XML mit Tag-Namen in HTML wie <table> oder <option> die Ergebnisse unvorhersehbar sein können. (EDIT: Seit 1.5 ist es jQuery.parseXML() das ist tatsächlich ein XML-Dokument konstruieren und damit diese Probleme vermeidet - nur für das Parsen.)

Um auf dem verboseness abgeholzt, eine kleine Helfer Bibliothek schreiben, oder vielleicht eine jQuery-Plugin um das Dokument zu konstruieren.

Hier ist eine schnelle und schmutzige Lösung zum Erstellen eines XML-Dokuments mit einem rekursiven Ansatz.

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

Rückkehr: ein guter Anfang zu sein für die Erstellung von XML von Grund auf (im Speicher), werfen Sie einen Blick auf diese

<report>​ 
    <submitter>​ 
     <name>​John Doe​</name>​ 
    </submitter>​ 
    <students>​ 
     <student>​ 
      <name>​Alice​</name>​ 
      <grade>​80​</grade>​ 
     </student>​ 
     <student>​ 
      <name>​Bob​</name>​ 
      <grade>​90​</grade>​ 
     </student>​ 
    </students>​ 
</report>​ 

See example

+4

Das kann oder darf nicht schnell + schmutzig sein, aber es ist definitiv sehr hübsch! – Tao

+8

Kombinieren Sie mit 'new XMLSerializer(). SerializeToString (yourXml)' und es bildet eine gute Möglichkeit, strukturierte Dokumente zum Senden in AJAX-Nachrichten zu erstellen. Hervorragend! –

+0

Dies ist, was ich brauche, aber irgendwie konnte ich es nicht funktionieren lassen, das http://jsfiddle.net/vquyT/1/ funktioniert auch nicht? Könnten Sie diesen Link aktualisieren oder fehlt mir etwas? –

2

Ich habe Ariel Flesler der XMLWriter Konstruktorfunktion gefunden

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

exampl

e
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()); 
} 

Ergebnis

<?xml version="1.0" encoding="ISO-8859-1" standalone="true" ?> 
<test foo="bar">Hello World</test> 

Ein paar Einschränkungen, spielt es keine Strings entkommen und die Syntax kann Kojote bekommen ++ hässlich.

+0

'' 'ReferenceError: XMLWriter ist nicht definiert''' (Chrome Version 30.0.1599.101 m) –

+0

@Michal Stefanow haben Sie die XmlWriter-Funktion hinzugefügt? –

+0

Ich habe den Link nicht angeklickt. Ich dachte, dass das Beispiel in sich abgeschlossen ist. –

4

Hinweis:

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

jquery schafft Elemente in Kleinbuchstaben, $("<topMenu />") und $("<topmenu />") schafft gleiche Elemente <topmenu />

Verwandte Themen