javascriptangularjsxml

How do I deep clone XMLDocument Object in Javascript?


I'm creating a tool that parses XML file into XMLDocument object. I'm using browser implementation of xml parser e.g.:

new DOMParser().parseFromString(text,"text/xml");

For some reason I should to have a copy of current XMLDocument object in another variable.

The question is - how to make deep clone of parsed xml object?

Thanks!


Solution

  • You use cloneNode(true), which Document inherits from Node:

    var d2 = d.cloneNode(true);
    

    Example:

    var d = new DOMParser().parseFromString(
      "<root><x><y></y></x></root>",
      "text/xml"
    );
    // Prove it's a deep clone by removing `y` from `x`:
    console.log("d before", d.documentElement.firstChild.children.length);
    var x = d.documentElement.firstChild;
    var d2 = d.cloneNode(true);
    x.removeChild(x.firstChild);
    console.log("d after", d.documentElement.firstChild.children.length);
    console.log("d2 after", d2.documentElement.firstChild.children.length);


    Eugene Ryabtsev points out that this won't clone the information from the prolog, which is a good point.

    As of this writing, the prolog information consists of:

    Of those, only the standalone flag is relevant. The version is always 1.0 as of this writing (even if you give a different 1.x value in the prolog, it's processed as an XML 1.0 document per spec); and the encoding isn't relevant because we're dealing with a document in memory, not text we're deserializing from bytes.

    But the standalone flag is indeed not copied by cloneNode (at least not on Chrome). If you also want to copy the standalone flag, add:

    d2.xmlStandalone = d.xmlStandalone;
    

    after cloneNode.