Why does the code continue to print items, while the list from which it is printed contains only one item?

advertisements

Why does the code continue to print elements, when the list it's printing from only has 1 element in it?


<?xml version="1.0"?>
<company>
    <staff id="1001">
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff id="2001">
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>


package com.mkyong.seo;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ReadXMLFile2 {

  public static void main(String[] args) {

    try {

    File file = new File("/Users/mkyong/staff.xml");

    DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
                             .newDocumentBuilder();

    Document doc = dBuilder.parse(file);

    System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

    if (doc.hasChildNodes()) {

        printNote(doc.getChildNodes());

    }

    } catch (Exception e) {
    System.out.println(e.getMessage());
    }

  }

  private static void printNote(NodeList nodeList) {

    for (int count = 0; count < nodeList.getLength(); count++) {

    Node tempNode = nodeList.item(count);

    // make sure it's element node.
    if (tempNode.getNodeType() == Node.ELEMENT_NODE) {

        // get node name and value
        System.out.println("\nNode Name =" + tempNode.getNodeName() + " [OPEN]");
        System.out.println("Node Value =" + tempNode.getTextContent());

        if (tempNode.hasAttributes()) {

            // get attributes names and values
            NamedNodeMap nodeMap = tempNode.getAttributes();

            for (int i = 0; i < nodeMap.getLength(); i++) {

                Node node = nodeMap.item(i);
                System.out.println("attr name : " + node.getNodeName());
                System.out.println("attr value : " + node.getNodeValue());

            }

        }

        if (tempNode.hasChildNodes()) {

            // loop again if has child nodes
            printNote(tempNode.getChildNodes());

        }

        System.out.println("Node Name =" + tempNode.getNodeName() + " [CLOSE]");

    }

    }

  }

}


OUTPUT:--

Root element :company

Node Name =company [OPEN]
Node Value =

        yong
        mook kim
        mkyong
        100000

        low
        yin fong
        fong fong
        200000

Node Name =staff [OPEN]
Node Value =
        yong
        mook kim
        mkyong
        100000

attr name : id
attr value : 1001

Node Name =firstname [OPEN]
Node Value =yong
Node Name =firstname [CLOSE]

Node Name =lastname [OPEN]
Node Value =mook kim
Node Name =lastname [CLOSE]

Node Name =nickname [OPEN]
Node Value =mkyong
Node Name =nickname [CLOSE]

Node Name =salary [OPEN]
Node Value =100000
Node Name =salary [CLOSE]
Node Name =staff [CLOSE]

Node Name =staff [OPEN]
Node Value =
        low
        yin fong
        fong fong
        200000

attr name : id
attr value : 2001

Node Name =firstname [OPEN]
Node Value =low
Node Name =firstname [CLOSE]

Node Name =lastname [OPEN]
Node Value =yin fong
Node Name =lastname [CLOSE]

Node Name =nickname [OPEN]
Node Value =fong fong
Node Name =nickname [CLOSE]

Node Name =salary [OPEN]
Node Value =200000
Node Name =salary [CLOSE]
Node Name =staff [CLOSE]
Node Name =company [CLOSE]

According to me the output shouldn't have passed beyond:-

Node Name =firstname [OPEN]
Node Value =low
Node Name =firstname [CLOSE]

1st time.

Please help


You're browsing through the XML as if it were a tree, going along each branch at a time. The reason the list you're printing only has 1 element in it, is because in that branch, you are at element firstname, which has 1 child, a text node saying 'low' when that finishes executing, you step back to the previous branch, and move on to that elements next child (lastname). This may become a little bit clearer if you add something to show which level of branch you are on (to show how deep you are down the tree), the code is the same, but i have added an integer 'depth' which is printed out to show the depth in the tree, which should help it become clearer how the recursion is working..

e.g.

package com.mkyong.seo;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ReadXMLFile2 {

public static void main(String[] args) {

try {

File file = new File("/Users/mkyong/staff.xml");

DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
                         .newDocumentBuilder();

Document doc = dBuilder.parse(file);

System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

if (doc.hasChildNodes()) {

    printNote(doc.getChildNodes(), 1);

}

} catch (Exception e) {
System.out.println(e.getMessage());
}

}

private static void printNote(NodeList nodeList, int depth) {

for (int count = 0; count < nodeList.getLength(); count++) {

Node tempNode = nodeList.item(count);

// make sure it's element node.
if (tempNode.getNodeType() == Node.ELEMENT_NODE) {

    // get node name and value
    System.out.println(depth + "\nNode Name =" + tempNode.getNodeName() + " [OPEN]");
    System.out.println(depth + "Node Value =" + tempNode.getTextContent());

    if (tempNode.hasAttributes()) {

        // get attributes names and values
        NamedNodeMap nodeMap = tempNode.getAttributes();

        for (int i = 0; i < nodeMap.getLength(); i++) {

            Node node = nodeMap.item(i);
            System.out.println("attr name : " + node.getNodeName());
            System.out.println("attr value : " + node.getNodeValue());

        }

    }

    if (tempNode.hasChildNodes()) {

        // loop again if has child nodes
        printNote(tempNode.getChildNodes(), depth+1);

    }

    System.out.println(depth + "Node Name =" + tempNode.getNodeName() + " [CLOSE]");

}

}

}

}