Java jdom2 - 递归地解析XML

时间:2016-11-14 19:55:16

标签: java xml recursion

我试图制作一个递归方法,可以使用以下格式的XML中的jdom2解析/遍历XML文档

 <rootElement>
       <result>
         <rowset>
            <row>
               <something>
               <rowset>
                  <row>
                  <row> <--- I get to here. NullPointerException
               <rowset>
                  <row>
         <rowset>
            <row>
               <something>
               <rowset>
                  <row>
                  <row>
               <rowset>
                  <row>

代码

diTest(document.getRootElement().getChildren().iterator(), 7);
private static Iterator<Element> diTest(Iterator<Element> list, Integer count) {
//      temp statement to avoid infinity loop.
        if (count == 0) {
            System.out.println("exited program");
            System.exit(0);
        }

//      Test to keep track of count in output.
        System.out.println("count is: " + count);

        Element element = null;

        while (list.hasNext()) {
            element = list.next();

            System.out.println(element.getName());
            if (element.hasAttributes()) {
                System.out.println(element.getAttributes());
            }

            if (element.getChildren().size() > 0) {
                System.out.println(element.getAttributes());
                System.out.println("");
                break;
            }
        }

        return diTest(element.getChildren().iterator(), count -1); //null pointer exception when it can't get more children on the last element... Need to go back somehow...
    }// recursive end

当方法抛出nullpointerexception时,我相信它,因为它试图从没有的元素中获取子元素。

问题:我如何解决这个问题,让方法意识到它需要步骤&#34;返回&#34;如果它找到了道路的末端,那么将a级别升级到下一个元素&#34;确保它实际上是道路的终点&#34;?

对此的任何和所有建议都非常受欢迎,因为我发现如何粗略地找到关于如何做到这一点的正确信息。要么我遇到的是我的水平还是那么简单以至于我无法将其应用到我想要解决的问题中。

示例:4 * 3 * 2 * 1(递归)

修改

感谢来自@Michael Kay的输入,我得到了一个读取整个XML文档的递归方法。

分享新方法

private static void diReadXmlRecursively(Iterator<Element> list) {
        Element element = null;

        while (list.hasNext()) {            
            element = list.next();

            System.out.println("Element name: " + element.getName());

            diReadXmlRecursively(element.getChildren().iterator());
        }
    }

1 个答案:

答案 0 :(得分:1)

考虑list是一个空迭代器的情况。您的代码是:

Element element = null;
while (list.hasNext()) {
    element = list.next();
    ....
}
return diTest(element.getChildren()...)

如果list.hasNext()上的第一个调用返回false,则不会对element进行分配,因此element.getChildren()上的调用将抛出NPE。

您还可以看到逻辑错误,因为方法的主体总是调用自身 - 如果不是NPE,则递归将是无限的。

您还可以看到逻辑错误,因为您只在最后元素子元素上调用getChildren(),而您可能想要递归每个元素子元素。

修复很简单:在循环中移动递归调用:

while (list.hasNext()) {
    Element element = list.next();
    ....
    return diTest(element.getChildren()...)
}

您的代码还有一些其他特殊的东西。 count变量是不必要的。如果一个元素有子元素,那么从循环中“中断”是没有意义的。仅当元素具有子元素时才显示元素的属性是没有意义的。

为什么方法返回一个迭代器,你希望这个迭代器包含什么?我希望你的方法什么都不返回(无效)。

并不是严格错误,但我的本能是在递归调用上传递列表,而不是列表上的迭代器。这是因为列表通常更有用,例如如果需要,您可以计算列表中的项目数。