简体   繁体   English

Java Jdom2-递归解析XML

[英]Java jdom2 - recursively parse XML

Im trying to make a recursive method that can parse / travel through an XML document using jdom2 in an XML with the following format 我正在尝试创建一种递归方法,该方法可以使用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>

Code

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

When the method throws the nullpointerexception i believe its because its trying to get the children from a element that has none. 当方法抛出nullpointerexception时,我相信它是因为它试图从没有元素的元素中获取子元素。

Question: How can i get past this problem, and make the method aware that it needs to step "back" up a level an onto the next element if it finds the "end of the road" to make sure that it is in fact the "end of the road"? 问题:我如何解决这个问题,并使方法意识到如果找到“道路的尽头”以确保实际上是“路的尽头”?

Any and all advice on this is very welcome, since i find it sketchy to find decent information on how to do this. 非常欢迎对此提出任何建议,因为我发现找到关于如何执行此操作的体面信息很粗略。 Either i come across what to me is out of my level or so simple that i cant apply it to the problem i am trying to solve. 我遇到的问题超出了我的水平,或者太简单了,无法将其应用于我要解决的问题。

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

Edit 编辑

Thanks to the input from @Michael Kay i got my recursive method to read the entire XML document. 感谢@Michael Kay的输入,我有了递归方法来读取整个XML文档。

Sharing new method 分享新方法

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());
        }
    }

Consider the case where list is an empty iterator. 考虑list是一个空迭代器的情况。 Your code is: 您的代码是:

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

If the first call on list.hasNext() returns false, then the assignment to element will not take place, therefore the call on element.getChildren() will throw an NPE. 如果对list.hasNext()的第一次调用返回false,则不会进行对element的赋值,因此对element.getChildren()的调用将引发NPE。

You can also see that the logic is wrong because the body of the method always calls itself - if it weren't for the NPE, the recursion would therefore be infinite. 您还可以看到逻辑是错误的,因为方法的主体始终会自行调用-如果不是NPE,则递归将是无限的。

You can also see that the logic is wrong because you only call getChildren() on the last element child, whereas you presumably want to recurse for every element child. 您还可以看到逻辑是错误的,因为您仅在最后一个元素子元素上调用getChildren(),而您可能想对每个元素子元素进行递归。

The fix is simple: move the recursive call inside the loop: 解决方法很简单:在循环内移动递归调用:

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

There are a few other peculiar things about your code. 您的代码还有其他一些奇特的事情。 The count variable is unnecessary. 计数变量是不必要的。 The "break" out of the loop if an element has children makes no sense. 如果元素有子元素,则“跳出”循环是没有意义的。 Displaying the attributes of an element only if it has children makes no sense. 仅当元素具有子元素时才显示其属性是没有意义的。

Why is the method returning an iterator, and what do you expect this iterator to contain? 为什么该方法返回迭代器,您希望该迭代器包含什么? I would expect your method to return nothing (void). 我希望您的方法不返回任何内容(无效)。

And it's not strictly wrong, but my instinct would be to pass the list on the recursive call, rather than an iterator over the list. 这不是严格错误,但是我的直觉是在递归调用上传递列表,而不是在列表上进行迭代。 That's because a list is generally more useful, eg you can count the number of items in the list if you want. 这是因为列表通常更有用,例如,您可以根据需要计算列表中的项目数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM