Создание XML-документа в памяти с помощью JavaScript
Я работаю над веб-приложением, которое должно отправлять XML на серверный сервер. Я хочу создать XML-документ в памяти на стороне клиента, но с использованием процедуры, XML, вместо добавления бесчисленных строк. Я надеюсь, что jQuery может помочь мне.
предположим, мне нужно создать этот (игрушечный) XML-документ с 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>
для начала мне нужно создать какой-то объект XML-документа с корнем "report". Я предполагаю, что один из они должны быть близки, но ни один из них не работает правильно, и / или я не могу понять, как правильно использовать объект:
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;
}
Теперь я хочу создавать и добавлять элементы. Как мне это сделать? Я думаю, что это что-то вроде этого:
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;
}
какие идеи?
5 ответов
не обращаясь ли вы должны используйте 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());
выход:
<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>
второй подход кажется хорошим способом пойти. Он был разработан для работы с 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);
это может показаться немного подробным, но это правильный способ создания XML-документа. jQuery фактически не создает XML-документ, а просто полагается на innerHTML свойство для разбора и восстановления DOM заданной строки HTML. Проблема в том, что подход заключается в том, что когда имена тегов в вашем XML сталкиваются с именами тегов в HTML, такими как <table> или <option>, тогда результаты могут быть непредсказуемыми.
(EDIT: с 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')
        )
    )
);
возвращает:
<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 создает элементы в нижнем регистре,$("<topMenu />") и $("<topmenu />") создает равные элементы <topmenu />
Я нашел функцию конструктора XmlWriter Ариэля Флеслера хорошим началом для создания XML с нуля (в памяти), взгляните на это
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>
несколько предостережений, он не избегает строк, и синтаксис может получить 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
}
