node.jsxmldom

How to manipulate a xml file and save it to disk?


I have two xml files with exactly same structure. The only difference is the inner text of the tags. I want to replace the value in the first file with the corresponding value in the second file.

I have tried using the xml2json but the problem is it removed all the comments which I need in the final output. So currently I am using xmldom. I am able to manipulate the text but the changes are lost when I try to save the file to the disk.

var DOMParser = require("xmldom").DOMParser;
var serializer = new (require('xmldom')).XMLSerializer;
var fs = require('fs');

let firstXML = `<root>
    <!--This is just a comment-->
    <string name="one">SOMETHING</string>
</root>`

let secondXML = `<root>
    <string name="one">ELSE</string>
</root>`

var firstDoc = new DOMParser().parseFromString(firstXML, "text/xml");
var secondDoc = new DOMParser().parseFromString(secondXML, "text/xml");

let elementsFirst = firstDoc.getElementsByTagName("string");
let elementsSecond = secondDoc.getElementsByTagName("string");

for(let i = 0; i < elementsFirst.length; ++i) {
    let el = elementsFirst[i];
    let name = el.getAttribute("name");
    for(let j = 0; j < elementsSecond.length; ++j) {

        if(name = elementsSecond[j].getAttribute("name")) {
            el.firstChild.nodeValue = elementsSecond[j].firstChild.nodeValue;
            break;
        }
    }
}

fs.writeFileSync("output.xml", serializer.serializeToString(firstDocs));

//Required output

`<root>
    <!--This is just a comment-->
    <string name="one">ELSE</string>
</root>`

Solution

  • Please don't ask me why, but if you replace this line

    el.firstChild.nodeValue = elementsSecond[j].firstChild.nodeValue;

    with this one

    el.firstChild.data = elementsSecond[j].firstChild.nodeValue;

    it will work as expected.

    P.S. You have a typo in your if statement, you need ===, a single = will usually return true

    Update: after finding the solution - I found out that it is duplicate of this one