Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

jquery - Generate XML document in-memory with JavaScript

I am working on a Web application that needs to send XML to a server backend. I'd like to build a XML document in-memory on the client-side, but using XML manipulation routines, instead of appending countless strings together. I'm hoping jQuery can help me out.

Let's say I need to generate this (toy) XML document with JavaScript:

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

To start, I need to create some kind of an XML document object with the "report" root. I'm assuming one of these should be close, but none of them work quite right, and/or I can't quite figure out how to use the object properly:

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

Now I want to create and append elements. How do I do that? I imagine it's something like this:

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

Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The second approach seems a good way to go. It was designed to work with XML documents. Once you have the document object created, use the standard XML DOM manipulation methods to construct the entire document.

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

This may seem a little verbose but is the right way to build the XML document. jQuery does not actually construct any XML document, but just relies on the innerHTML property to parse and reconstruct a DOM given an HTML string. The problem with that approach is that when tag names in your XML collide with tag names in HTML such as <table> or <option>, then the results can be unpredictable. (EDIT: since 1.5 there's jQuery.parseXML() which does actually construct an XML document and thus avoids these problems — for parsing only.)

To cut down on the verboseness, write a small helper library, or maybe a jQuery plugin to construct the document.

Here's a quick and dirty solution to creating a XML document using a recursive approach.

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

Returns:

<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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...