1

I am trying to parse a few specific parts of an xml doc. I am looking at pulling the data out of the analysis section, I need the warnings, errors, passes and I need to go into each of the sections () and get the result and result level and the text for example in this "ERROR" I would need to get level of error and the text "ERROR".

<document>
    <configuration>
    </configuration>
    <data>
    </data>
    <analysis warnings="5" errors="3" information="0" passed="false">
        <files>
        </files>
        <results>
            <form>
                <section number="0">
                    <result level="error">ERROR</result>
                    <result level="error">ERROR</result>
                    <result level="error">ERROR</result>
                    <result level="warning">Warning</result>
                    <result level="warning">Warning</result>
                </section>
                <section number="1">
                    <result level="warning">WARNING</result>
                </section>
                <section number="2">
                    <result level="warning">WARNING</result>
                    <result level="warning">WARNING</result>
                </section>
            </form>
        </results>
    </analysis>
</document>

I have the following code:

public void ProcessXMLFromPath(String path) throws Exception
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document =  builder.parse(path);
        NodeList nodeList = document.getDocumentElement().getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
          Node node = nodeList.item(i);
          if (node instanceof Element) {
            System.out.println(node.getAttributes().toString());
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
              Node cNode = childNodes.item(j);

              if (cNode instanceof Element) {
                  System.out.println(cNode.getNodeName().toString()); 
                  if(cNode.getNodeName().toString() == "analysis")
                  {
                      String content = cNode.getLastChild().getTextContent().trim();
                      System.out.println(content);
                      //I thought this would print the children under the analysis section to the screen but I was mistaken. It does however make it to this point.
                  }
              }
            }

          }

        }
    }

The only thing I'm getting to print to my console is:

configuration
data
analysis

Any help would be greatly appreciated!

user1857654
  • 183
  • 1
  • 5
  • 22

2 Answers2

1

A couple of issues with the code:

  1. cNode.getNodeName().toString() == "analysis", do a String comparison with .equals
  2. analysis is the direct descendant of document (per the xml piece we have here), so it has to be checked early on. Your code checks for it at level 3 instead of 2
  3. You would need to drill further down the analysis to get the results, form and text nodes.

EDIT: Based on comments, an efficient way to traverse without the multiple for loops woild be recursion, as below:

public static void main(String[] args) throws ParserConfigurationException,
        SAXException, IOException {
    InputStream path = new FileInputStream("sample.xml");
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(path);
    traverse(document.getDocumentElement());

}

public static void traverse(Node node) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        Node currentNode = list.item(i);
        traverse(currentNode);

    }

    if (node.getNodeName().equals("result")) {
        System.out.println("This -> " + node.getTextContent());
    }

}

This gives the result as:

This -> ERROR
This -> ERROR
This -> ERROR
This -> Warning
This -> Warning
This -> WARNING
This -> WARNING
This -> WARNING
StoopidDonut
  • 8,547
  • 2
  • 33
  • 51
  • Is there a way to get it to parse individually line by line? Right now it prints the error and warning messages as 1 big block of text. – user1857654 Feb 03 '14 at 16:14
  • Is there anyway you could show me by updating your answer? I attempted to iterate but I keep making for for loops and trying to branch down and I know their has to be a better way. – user1857654 Feb 03 '14 at 17:27
  • @user1857654 updated the code above with the most efficient way (through recursion) and depicts your traversed nodes too – StoopidDonut Feb 03 '14 at 18:10
  • Boss, Thanks! Works great it looks way better than the for loops I was doing. – user1857654 Feb 03 '14 at 18:36
  • @user1857654 you're welcome, yes this is a way better approach. – StoopidDonut Feb 03 '14 at 20:35
0

For each of these three (configuration, data, analysis), get their child nodes and drill down until you get to your errors (i.e. to your result tags). You will find these below analysis (but not directly below it). So you can just drill down from analysis downwards.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • How would one go about doing that? Like how would I drill down into each section and subsection? – user1857654 Jan 31 '14 at 19:23
  • In the same way you got from `document` to `analysis`. Calling `getChildNodes()`. – peter.petrov Jan 31 '14 at 19:26
  • Is there a better/cleaner way to do it? right now I'm seeing that I'll have several nested for loops and it looks really dirty. – user1857654 Jan 31 '14 at 19:45
  • Maybe you could look at XPath. http://stackoverflow.com/questions/2811001/how-to-read-xml-using-xpath-in-java http://stackoverflow.com/questions/340787/parsing-xml-with-xpath-in-java – peter.petrov Jan 31 '14 at 19:46
  • Another approach is to use another parser - e.g. SAX Parser or StAX Parser. Maybe that would be better for your case, if you're only interested in these `result` errors there. You're using a DOM Parser now. – peter.petrov Jan 31 '14 at 19:47