views:

1129

answers:

2

Say you in JavaScript are handed a single DOM element or Document (for example window.document), how would you turn that into valid XML?

More specifically for my example, I have a web page that display's an SVG, this SVG has a lot of JavaScript to allow interaction. It's a graph display that let's you zoom in the graph and even make some transformations. Now the users off this want's to have a "Save image" button. The way I imagine doing this is to take the document node for the SVG element, and convert it into XML, then send that to the server, which then returns a page with the SVG document, or a PNG image.

This is all running on FireFox (which is currently a requirement for the users, though it works fine in Safari and Chrome as well). In firefox in the web page, I have included the SVG document as an Object element. In javascript I can access that objects contentDocument, that refers to the root off the XML page. It contains XML version, a Document tag, and the root svg tag with all attributes.

Maybe someone has already solved this, so I can copy their code. Perhaps someone knows where to look in firebug to achieve this. Or maybe there are already DOM methods for this.

+3  A: 

There is a non-standard API object: XMLSerializer (it is not standard though is implemented in all but IE browsers).

Its serializeToString method expects DOMNode object to be passed.

var sXML = new XMLSerializer().serializeToString(document.body);

In Internet Explorer there is no way to retrieve proper XML for HTML, unless getting .outerHTML and fixing all problems that come with serialization to HTML (such as missing quotes in attributes, not closed tags etc.)

Sergey Ilinsky
+1  A: 

I will have to look into XMLSerializer tomorrow. Here is the code I ended up writing instead, in case anyone is interested (requires prototype and FireBug for unknown nodes):

function extractXML(node) {
    switch (node.nodeType) {
        case 1: return extractNodeXML(node);
        case 2: return extractAttributeXML(node);
        // 3 = Text node
        case 3: return node.nodeValue;
        // 8 = Comment node - ignore
        case 8: return "";
        case 9: return extractDocumentNodeXML(node);
        case 10: return extractDocumentTypeXML(node);
        default: console.log(node); return "Unkwon type: "+node.nodeType;
    }
}
function extractNodeXML(node) {
    var xml = "<"+node.nodeName;
    $A(node.attributes).each(function (node) {xml += " "+extractXML(node)});
    xml +=">"
    $A(node.childNodes).each(function (node) {xml += extractXML(node)});
    xml += "</"+node.nodeName+">"
    return xml;
}
function extractAttributeXML(node) {
    return node.nodeName+"=\""+node.nodeValue+"\""
}
function extractDocumentNodeXML(node) {
    var xml = "<?xml version=\""+node.xmlVersion+"\" encoding=\""+node.xmlEncoding+"\"?>"
    $A(node.childNodes).each(function (node) {xml += extractXML(node)});
    return xml;
}
function extractDocumentTypeXML(node) {
    return "<!DOCTYPE "+node.name+" PUBLIC \""+node.publicId+"\" \""+node.systemId+"\">"
}
Staale