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]");
}
}
}
}