58

Is it possible to create an XML file with some data in JavaScript? I have the data stored in variables.

I've googled around a bit and it doesn't seem like it's talked about much. I thought I could use XMLWriter such as this:

var XML = new XMLWriter();
XML.BeginNode ("testing");
XML.Node("testingOne");
XML.Node("TestingTwo");
XML.Node("TestingThree");
XML.EndNode();

as stated in this tutorial: EHow Tutorial

However, when I execute this code, I get the following error:

ReferenceError: XMLWriter is not defined

How can I solve this error?

TylerH
  • 20,799
  • 66
  • 75
  • 101
BigBug
  • 6,202
  • 23
  • 87
  • 138
  • 2
    I think you can make an XML object by manipulating the DOM using usual methods, and then turn it into a string it with `innerHTML`. – Waleed Khan Jan 15 '13 at 15:26
  • 1
    See http://flesler.blogspot.com/2008/03/xmlwriter-for-javascript.html This is a separate js file you need to reference. Did you do that? – OldProgrammer Jan 15 '13 at 15:27
  • 1
    As far as I know, there's no `XMLWriter` object in vanilla JavaScript. The article probably explains how to use some third-party library. Whatever, it's a weird article—its formatting issues make me think that the content was grabbed from some other site and they omitted the link to the library. – Álvaro González Jan 15 '13 at 15:27
  • @LeorA, no i don't do that, is there a way to create XML without using any third party library? – BigBug Jan 15 '13 at 15:28
  • @WaleedKhan: That would not necessarily generate valid XML (think HTML elements without closing tags, special names for character entities, *etc.*). – PleaseStand Jan 15 '13 at 15:29
  • Even you create an xml file, it is not possible to write it on a disk using JavaScript. Do you want it to send it to server? Whats the purpose, please specify and we can help you better. – srijan Jan 15 '13 at 15:29
  • @srijan is correct. You would have to use some platform-depentant library, like an activex object for IE, not sure what chrome, etc. allow, but it would be plarform-specific. – OldProgrammer Jan 15 '13 at 15:33
  • it will be sent to java code at the end or something, i'm not too sure about the whole process, it just needs to be created in memory – BigBug Jan 15 '13 at 15:33
  • okay, i can use ActiveXObject, i see it being used elsewhere in the same file – BigBug Jan 15 '13 at 15:34
  • I believe ActiveX works only on Windows and only on IE. – srijan Jan 15 '13 at 15:35
  • @srijan that's fine, do you have a quick example i can look at to get started? – BigBug Jan 15 '13 at 15:37
  • 1
    I find @Seb3736 's answer to be a good one. Maybe it is time to check as valid some answer :) – Alfonso Nishikawa Oct 19 '17 at 15:27
  • The source library referenced in your code is here (date 2005) should you want to know or use it: https://www.codeproject.com/Articles/12504/Writing-XML-using-JavaScript – user3051040 Apr 12 '19 at 02:48

7 Answers7

101

Disclaimer: The following answer assumes that you are using the JavaScript environment of a web browser.

JavaScript handles XML with 'XML DOM objects'. You can obtain such an object in three ways:

1. Creating a new XML DOM object

var xmlDoc = document.implementation.createDocument(null, "books");

The first argument can contain the namespace URI of the document to be created, if the document belongs to one.

Source: https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument

2. Fetching an XML file with XMLHttpRequest

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {

    var xmlDoc = xhttp.responseXML; //important to use responseXML here
}
xhttp.open("GET", "books.xml", true);
xhttp.send();

3. Parsing a string containing serialized XML

var xmlString = "<root></root>";
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(xmlString, "text/xml"); //important to use "text/xml"

When you have obtained an XML DOM object, you can use methods to manipulate it like

var node = xmlDoc.createElement("heyHo");
var elements = xmlDoc.getElementsByTagName("root");
elements[0].appendChild(node);

For a full reference, see http://www.w3schools.com/xml/dom_intro.asp

Note: It is important, that you don't use the methods provided by the document namespace, i. e.

var node = document.createElement("Item");

This will create HTML nodes instead of XML nodes and will result in a node with lower-case tag names. XML tag names are case-sensitive in contrast to HTML tag names.

You can serialize XML DOM objects like this:

var serializer = new XMLSerializer();
var xmlString = serializer.serializeToString(xmlDoc);
Sebastian
  • 1,710
  • 2
  • 16
  • 28
  • I was looking to do this in the context of TVJS, where you don't have a `document` variable to retrieve the `document.implementation` from. Instead I had to use `DOMImplementationRegistry.getDOMImplementation()`. – Bruno De Fraine Sep 06 '16 at 10:52
30

Consider that we need to create the following XML document:

<?xml version="1.0"?>
<people>
  <person first-name="eric" middle-initial="H" last-name="jung">
    <address street="321 south st" city="denver" state="co" country="usa"/>
    <address street="123 main st" city="arlington" state="ma" country="usa"/>
  </person>

  <person first-name="jed" last-name="brown">
    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
    <address street="123 west st" city="seattle" state="wa" country="usa"/>
    <address street="321 south avenue" city="denver" state="co" country="usa"/>
  </person>
</people>

we can write the following code to generate the above XML

var doc = document.implementation.createDocument("", "", null);
var peopleElem = doc.createElement("people");

var personElem1 = doc.createElement("person");
personElem1.setAttribute("first-name", "eric");
personElem1.setAttribute("middle-initial", "h");
personElem1.setAttribute("last-name", "jung");

var addressElem1 = doc.createElement("address");
addressElem1.setAttribute("street", "321 south st");
addressElem1.setAttribute("city", "denver");
addressElem1.setAttribute("state", "co");
addressElem1.setAttribute("country", "usa");
personElem1.appendChild(addressElem1);

var addressElem2 = doc.createElement("address");
addressElem2.setAttribute("street", "123 main st");
addressElem2.setAttribute("city", "arlington");
addressElem2.setAttribute("state", "ma");
addressElem2.setAttribute("country", "usa");
personElem1.appendChild(addressElem2);

var personElem2 = doc.createElement("person");
personElem2.setAttribute("first-name", "jed");
personElem2.setAttribute("last-name", "brown");

var addressElem3 = doc.createElement("address");
addressElem3.setAttribute("street", "321 north st");
addressElem3.setAttribute("city", "atlanta");
addressElem3.setAttribute("state", "ga");
addressElem3.setAttribute("country", "usa");
personElem2.appendChild(addressElem3);

var addressElem4 = doc.createElement("address");
addressElem4.setAttribute("street", "123 west st");
addressElem4.setAttribute("city", "seattle");
addressElem4.setAttribute("state", "wa");
addressElem4.setAttribute("country", "usa");
personElem2.appendChild(addressElem4);

var addressElem5 = doc.createElement("address");
addressElem5.setAttribute("street", "321 south avenue");
addressElem5.setAttribute("city", "denver");
addressElem5.setAttribute("state", "co");
addressElem5.setAttribute("country", "usa");
personElem2.appendChild(addressElem5);

peopleElem.appendChild(personElem1);
peopleElem.appendChild(personElem2);
doc.appendChild(peopleElem);

If any text need to be written between a tag we can use innerHTML property to achieve it.

Example

elem = doc.createElement("Gender")
elem.innerHTML = "Male"
parent_elem.appendChild(elem)

For more details please follow the below link. The above example has been explained there in more details.

https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/How_to_create_a_DOM_tree

kkk
  • 1,850
  • 1
  • 25
  • 45
9

xml-writer(npm package) I think this is the good way to create and write xml file easy. Also it can be used on server side with nodejs.

var XMLWriter = require('xml-writer');
xw = new XMLWriter;
xw.startDocument();
xw.startElement('root');
xw.writeAttribute('foo', 'value');
xw.text('Some content');
xw.endDocument();
console.log(xw.toString());
qant
  • 183
  • 1
  • 2
  • 11
3

Simply use

var xmlString = '<?xml version="1.0" ?><root />';
var xml = jQuery.parseXML(xml);

It's jQuery.parseXML, so no need to worry about cross-browser tricks. Use jQuery as like HTML, it's using the native XML engine.

metadings
  • 3,798
  • 2
  • 28
  • 37
  • 3
    Note that in many cases, trying to using jQuery on XML as you would with HTML will cause a lot of head aches. jQuery sucks at XML, functions like 'replaceWith', 'after', 'before' only work on HTML nodes, not XML nodes. (these functions expect the object to have an 'innerHTML' property) – Drkawashima Aug 05 '14 at 10:47
3

this work for me..

var xml  = parser.parseFromString('<?xml version="1.0" encoding="utf-8"?><root></root>', "application/xml");

developer.mozilla.org/en-US/docs/Web/API/DOMParser

elad gasner
  • 655
  • 7
  • 7
2

Only works in IE

 $(function(){

        var xml = '<?xml version="1.0"?><foo><bar>bar</bar></foo>'; 

        var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async="false";
        xmlDoc.loadXML(xml);

        alert(xmlDoc.xml);

    });

Then push xmlDoc.xml to your java code.

srijan
  • 1,504
  • 1
  • 13
  • 24
0

Your code is referencing this library

You can include it, and then your code in question should run as is. If you want to do this without prepending the library & build it with builtin functions only - follow answer from @Seb3736.

In Browser Example

<html>
<head>
    <script src="Global.js" language="javascript"></script>
    <script src="XMLWriter.js" language="javascript"></script>
    <script language="javascript" type="text/javascript">
        function genXML(){
            var XML = new XMLWriter();
            XML.BeginNode ("testing");
            XML.Node("testingOne");
            XML.Node("TestingTwo");
            XML.Node("TestingThree");
            XML.EndNode();
            //Do something... eg.
            console.log(XML.ToString); //Yes ToString() not toString()
        }
    </script>
</head>
<body>
    <input type="submit" value="genXML" onclick="genXML();">
</body>
</html>

user3051040
  • 161
  • 1
  • 11