0

I have the following JavaScript code to "display" XML on a website:

function createChild(node,tabindex){

    var child = node.childNodes;

    var r = '';

    var tabs = '';

    for(i=0;i<tabindex;i++){

        tabs += "\t";

    };

    for(i=0;i<child.length;i++){

        if(child[i].nodeType == 1){

            r += tabs+"&lt;"+child[i].nodeName+"&gt;\n";

            if(child[i].hasChildNodes()){ r += createChild(child[i],1); }; // here is where it fails!

            r += tabs+"&lt;/"+child[i].nodeName+"&gt;\n";

        }

    }

    return r;

 };


function parseXML(xml){

    var doc = new DOMParser().parseFromString(xml,'application/xml');

    var node = doc.getElementsByTagName('*')[0];

    var r = '';

    r += "&lt;<span class=\"highlight highlight-blue\">"+node.nodeName+"</span>&gt;\n";

    if(node.hasChildNodes()){ r += createChild(node,1); };

    r += "&lt;<span class=\"highlight highlight-blue\">/"+node.nodeName+"</span>&gt;\n";

    $('.viewer').html(r);
};

This works fine on XML like this:

<properties>
    <property></property>
</properties>

But it fails to work when there is more than one child like this:

<properties>
    <property>
        <value></value>
    </property>
</properties>

The code keeps running until my browser crashes. I think there is an infinite loop in it, but I'm not sure. Does anyone have a tip for me?

4
  • 1
    "I think there is an infinite loop in it, but I'm not sure" You can use your debugger and then you will know. Commented Aug 3, 2017 at 15:35
  • browser crashes when I launch the code. My console is not showing anything. Commented Aug 3, 2017 at 15:36
  • 1
    So put a breakpoint on the first line of code and stop letting it execute... Commented Aug 3, 2017 at 15:37
  • when I remove the following "r += createChild(child[i],1);" and I put in a console.log('text')... I works. So the problem is with the createChild function obviously. But I'm asking this question because I cannot find the problem. Commented Aug 3, 2017 at 15:39

1 Answer 1

3

This is why you should always declare your variables:

// declare 'i'
for(var i = 0; i < tabindex ; i++){
  tabs += "\t";
};

If you don't declare i in the function scope, it will be global, thus interfering with the for loop in a recursive function call:

  1. The i variable is set to 0 in the first function call.

  2. The function is calls itself.

  3. The i variable is set to 0.

  4. The function returns.

  5. i is now 0 again, so the loop in the first frame will run forever.

So somewhere in the createChild function, you have to declare i, either before the first loop or in the first loop. You can also use let.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.