April 20, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Working with XML and Java, Page 3

  • January 2, 2008
  • By Rob Lybarger
  • Send Email »
  • More Articles »

With a fully-loaded Document object at your disposal, you now are ready to start using some of the accessor methods, mentioned earlier, to walk through the XML file structure and look at information. The first thing you probably want is to call getFirstChild() on the Document to get the root node. In your case, this is the "demo" element. To illustrate:

Node rootNode = doc.getFirstChild();
System.out.println("Root node name is "+rootNode.getNodeName());

Now, try working with a NodeList for all Nodes under your rootNode element:

NodeList nodes = rootNode.getChildNodes();
System.out.println("There are "+nodes.getLength()+"
                   total nodes.");

If you try that with the demo.xml file given above, you should get a message saying there are five nodes. Would you expect that? (Why not two nodes?) Be careful to note that getChildNodes() returns all nodes of all types—this includes the empty text present in your formatting such as the newline and tab characters. (If you carefully remove all the formatting, you will see the NodeList only has two nodes.) This means that, if you want to loop through all the children of a given node, but only work with actual Element nodes, you need to check the node type and skip anything not of interest. To count only Element-type Nodes in a given NodeList, for example, do the following:

int count=0;
for (int i=0 ; i<nodes.getLength() ; i++) {
   Node node = (Node) nodes.item(i);
   if (node.getNodeType() == Node.ELEMENT_NODE) {
      count++;
   }
}
System.out.println("There are "+count+" Element nodes.");

Now, you should have the number you might have naïvely expected earlier: two. As an alternative to checking getNodeType() and comparing it to the named constant in the Node interface, you also could check if (node instanceof Element). You will get the same effect in this case.

The last item that bears discussion is working with attributes of an element. Consider:

Element child1 = (Element) nodes.item(1);
NamedNodeMap nodeMap = child1.getAttributes();
for (int i=0 ; i<nodeMap.getLength() ; i++) {
   Node node = nodeMap.item(i);
   String name = node.getNodeName();
   String value = node.getNodeValue();
   System.out.println("Attribute ("+name+") has value
                      ("+value+")");
}

In this particular case, because I "know" that nodes.item(1) is an Element, I can cast it to an Element type. (This is not a requirement for the code to function, and when you don't "know" ahead of time, consider checking with getNodeType() or using the instanceof operator.) The API docs state that calling getAttributes returns null for anything other than when called on an Element, and that it [only] returns Attribute nodes. This being the case, you can skip on some node type checking in this area and get straight to the business of asking each attribute Node for its name and its value.

When your assumptions about node types go wrong—as might be the case for adding an extra blank line in just the right (wrong?) spot of the file above—you'll get ClassCastExceptions (or something similar) thrown at you. Code other than what is present in a demonstrational article should take all necessary precautions to insulate itself from the developer's assumptions and the user's actions. (The time you think you'll save now will be paid back, with interest, in debugging later.)

Here's the completed demo code, including the various lazy "don't do this" shortcuts I've already warned you about:

import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

public class Demo {
  public static void main(String[] args) {

    String FILE_NAME = "demo.xml";
    File file = new File(FILE_NAME);
    if ( ! (file.exists() && file.canRead())) {
      System.err.println("Error: cannot read "+FILE_NAME+".
                         Exiting now.");
      System.exit(1);
    }
    try {
      DocumentBuilderFactory dbFactory =
         DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = dbFactory.newDocumentBuilder();
      Document doc = builder.parse(file);

      Node rootNode = doc.getFirstChild();
      System.out.println("Root node name: " +
                         rootNode.getNodeName());

      NodeList nodes = rootNode.getChildNodes();
      System.out.println("There are "+ nodes.getLength() + "
                         total nodes.");

      int count=0;
      for (int i=0 ; i<nodes.getLength() ; i++) {
        Node node = nodes.item(i);
        if (node instanceof Element) {
          count++;
        }

      System.out.println("There are "+count+" Element nodes.");

      Element child1 = (Element) nodes.item(1);
      NamedNodeMap nodeMap = child1.getAttributes();
      for (int i=0 ; i<nodeMap.getLength() ; i++) {
        Node node = nodeMap.item(i);
        String name = node.getNodeName();
        String value = node.getNodeValue();
        System.out.println("Attribute ("+name+") has value
                           ("+value+")");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }
}




Page 3 of 5



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel