I have a simple XML representation of a table below. When I traverse the top level only, with the code (included below). I get 5 nodes, when infact there are only 2 in the example provided (theader and tbody). Can someone please explain why ?
package testparser;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class TestParser {
private static final int FILE_small = 1;
private static final int FILE_medium = 2;
private static final int FILE_large = 3;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
doDomTest(1);
}
private static void doDomTest(int sizeId) {
String filename = getFileNameFromId(sizeId);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
FileInputStream fis = new FileInputStream(filename);
Document doc = db.parse(fis);
Element topElement = doc.getDocumentElement();
NodeList nl = topElement.getChildNodes();
int ilen = nl.getLength();
print("Top Element count " + ilen);
for (int i=0;i<ilen;i++){
Node node = nl.item(i);
if (node.getNodeType()==Node.TEXT_NODE) {
print(i + ". Name:" + node.getNodeName() + "= " + node.getNodeValue() + ". type " + node.getNodeType());
} else {
print(i + ". Name:" + node.getNodeName() + ", type " + node.getNodeType());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getFileNameFromId(int sizeId) {
String sReturn = "";
switch (sizeId) {
case FILE_small:
sReturn = "D:/temp/testdata_ok.xml";
break;
case FILE_medium:
sReturn = "D:/temp/testdata_ok.xml";
break;
case FILE_large:
sReturn = "D:/temp/testdata_ok.xml";
break;
}
return sReturn;
}
private static void print(String sValue) {
System.out.println(sValue);
}
}
TEST DATA
<?xml version="1.0" encoding="utf-8"?>
<table>
<theader>
<tr>
<th>Title Col1</th>
<th>Title Col2</th>
<th>Title Col3</th>
<th>Title Col4</th>
</tr>
</theader>
<tbody>
<tr>
<td>data:R1C1</td>
<td>data:R1C2</td>
<td>data:R1C3</td>
<td>data:R1C4</td>
</tr>
<tr>
<td>data:R2C1</td>
<td>data:R2C2</td>
<td>data:R2C3</td>
<td>data:R2C4</td>
</tr>
<tr>
<td>data:R3C1</td>
<td>data:R3C2</td>
<td>data:R3C3</td>
<td>data:R3C4</td>
</tr>
<tr>
<td>data:R4C1</td>
<td>data:R4C2</td>
<td>data:R4C3</td>
<td>data:R4C4</td>
</tr>
<tr>
<td>data:R5C1</td>
<td>data:R5C2</td>
<td>data:R5C3</td>
<td>data:R5C4</td>
</tr>
</tbody>
</table>
Console Output
Top Element count 5
0. Name:#text=
. type 3
1. Name:theader, type 1
2. Name:#text=
. type 3
3. Name:tbody, type 1
4. Name:#text=
. type 3
Note how theader and tbody (lines 1 and 3) are reported in the output but I also have items 0,2, and 4. Why the extra nodes ? I would have expected just lines listing 0 and 1 for theader and tbody respectively.
The "type 1"/"type 3" represents value of the "getNodeType()" method also printed in the output. I found getNodeType() meaning here.
I am using JDK 1.6.0u24
The three extra nodes are text nodes that represent the white space:
<table>
and <theader>
</theader>
and <tbody>
, and</tbody>
and </table>
.I'm not sure about this, but I think you could eliminate the nodes by calling
dbf.setIgnoringElementContentWhitespace(true);
Read the javadoc, paying attention to the bit that says that the parser must be in validating mode ...