javascriptnode.jsrecursionlibxml-js

RangeError in libxmljs in NodeJS


I'm trying to replace lengthy XML tags with int values. Example '' as '<1>' so every tag with the name 'child' in the whole XML file will be replaces as '1'. I'm using libxmljs in NodeJS for this. So far my code is ;

    var libxml = require('libxmljs');
var xml =  '<?xml version="1.0" encoding="UTF-8"?>' +
           '<root>' +
               '<child foo="bar">' +
                   '<grandchild baz="fizbuzz">grandchild content</grandchild>' +
               '</child>' +
               '<child foo="bar1">' +
                   '<grandchild baz="fizbuzz">grandchild content 1</grandchild>' +
               '</child>' +
               '<sibling>with content!</sibling>' +
           '</root>';


var xmlDoc = libxml.parseXml(xml);
var allxml = xmlDoc.root();  //store all nodes as allxml
var allNodes = xmlDoc.childNodes(); //all child nodes to array
rec(allxml);

function rec(anElement){
for (var j=0; j<allNodes.length;j++ )
    {
        var firstnode = allNodes[j].name(); //get tagname of the element

        var findelem = xmlDoc.find(firstnode); //find similar elements with the tagname to array
        var currChild = xmlDoc.child(j); //get current child element
        var currnode = xmlDoc.childNodes(); // child nodes of current element to array
        if (hasChild(currChild)) { // check whether this has child elements
                rec(currChild.childNodes()); //if yes recall this function
            }
        else{ replaceCurrentTag(findelem, j);} // if no child nodes replace the name
    }
}

function replaceCurrentTag(currelem, j){

for (var i=0;i<currelem.length;i++){
        currelem[i].name(j.toString());
    }
}

function hasChild(xmlElement){
var e = xmlElement.childNodes();
if (e.length > 0){ return true; }
else return false;
}

console.log(xmlDoc.toString());

But I'm getting this error when I run it in terminal.

/home/compaq/node_modules/libxmljs/lib/document.js:0
(function (exports, require, module, __filename, __dirname) { var bindings = r
^
RangeError: Maximum call stack size exceeded

What is that I'm doing wrong in here.

Please help. Thank you


Solution

  • Your rec function iterates over allNodes, rather than the some subset of the nodes (probably the children of anElement). Combined with recursing into rec again before calling replaceCurrentTag (which never gets called), your function continues to call rec until you fill the call stack.