使用JavaScript在内存中生成XML文档

Sha*_*rog 36 javascript xml jquery

我正在开发一个需要将XML发送到服务器后端的Web应用程序.我想在客户端内部构建一个XML文档,但是使用XML操作例程,而不是将无数字符串附加在一起.我希望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>
Run Code Online (Sandbox Code Playgroud)

首先,我需要使用"report"根创建某种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;
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建和追加元素.我怎么做?我想它是这样的:

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;
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Anu*_*rag 63

第二种方法似乎是一个很好的方法.它旨在使用XML文档.创建文档对象后,使用标准XML DOM操作方法构造整个文档.

// 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);
Run Code Online (Sandbox Code Playgroud)

这看起来有点冗长,但却是构建XML文档的正确方法.jQuery实际上并不构造任何XML文档,而只是依赖于innerHTML属性来解析和重构给定HTML字符串的DOM.这种方法的问题在于,当XML中的标记名称与HTML中的标记名称冲突(例如<table>或)时<option>,结果可能是不可预测的.(编辑:自1.5有jQuery.parseXML()实际构造XML文档,从而避免了这些问题-只为解析.)

要减少冗长,请编写一个小帮助程序库,或者编写一个jQuery插件来构建文档.

这是使用递归方法创建XML文档的快速而肮脏的解决方案.

// 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')
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

返回:

<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>?
Run Code Online (Sandbox Code Playgroud)

见例子

  • 结合`new XMLSerializer().serializeToString(yourXml)`,它构成了构建结构化文档以便在AJAX消息中发送的好方法.高超! (8认同)
  • 这可能是也可能不是快速+肮脏,但它绝对非常漂亮! (4认同)

rat*_*ath 26

如果不解决是否应该使用jQuery构建XML,这里有一些关于如何实现它的想法:

// 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());
Run Code Online (Sandbox Code Playgroud)

输出:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 这种方法的一个问题是HTML标记名称不区分大小写,而在XML中它们区分大小写.因此,jQuery会将所有标记转换为小写,这可能不是您想要的. (4认同)