用JavaScript生成内存中的XML文档

我正在开发一个需要将XML发送到服务器后端的Web应用程序。 我想在客户端在内存中构build一个XML文档,但使用XML操作例程,而不是将无数的string附加在一起。 我希望jQuery能帮助我。

假设我需要用JavaScript生成这个(玩具)XML文档:

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

首先,我需要用“report”根创build某种XML文档对象。 我假设其中一个应该是接近的,但没有一个是正确的,和/或我不能完全弄清楚如何正确使用这个对象:

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

现在我想创build和追加元素。 我怎么做? 我想像是这样的:

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

有任何想法吗?

没有解决你是否应该使用jQuery来构buildXML,这里有一些关于如何做的build议:

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

输出:

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

第二种方法似乎是一个好方法。 它被devise用于处理XML文档。 一旦创build了文档对象,就可以使用标准的XML DOM操作方法来构build整个文档。

 // creates a Document object with root "<report>" var doc = document.implementation.createDocument(null, "report", null); // create the <submitter>, <name>, 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); 

这看起来有点冗长,但是构buildXML文档的正确方法。 jQuery实际上并不构build任何XML文档,只是依赖于innerHTML属性来parsing和重构给定HTMLstring的DOM。 这种方法的问题是,当XML中的标签名称与HTML中的标签名称(如<table><option>冲突时,结果可能是不可预知的。 (编辑:自1.5有jQuery.parseXML()它实际上构造一个XML文档,从而避免了这些问题 – 只parsing。)

为了减less冗长,可以写一个小型的帮助程序库,或者一个jQuery插件来构build文档。

下面是使用recursion方法创buildXML文档的一个快速和肮脏的解决scheme。

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

返回:

 <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>​ 

看例子

注意:

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

jquery以小写forms创build元素, $("<topMenu />")$("<topmenu />")创build相同的元素<topmenu />

我发现Ariel Flesler的XMLWriter构造函数是从头开始创buildXML(在内存中)的一个好的开始,看看这个

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

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

结果

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

一些警告,它不逃避string和语法可以得到coyote ++丑陋。

你有没有考虑过JSON? 您可以使用对象保存数据。 那么你可以使用JSON.stringify(obj); 并发送到服务器。

一个简单的例子

 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 }