在 Java DOM 中迭代所有 XML 节点生成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1034062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:30:16  来源:igfitidea点击:

Iterate all XML node generations in java DOM

javaxmldom

提问by directedition

I want to check to see if an XML document contains a 'person' element anywhere inside. I can check all the first-generation elements very simply:

我想检查一个 XML 文档是否在内部的任何地方包含“person”元素。我可以非常简单地检查所有第一代元素:

NodeList nodeList = root.getChildNodes();
for(int i=0; i<nodeList.getLength(); i++){
  Node childNode = nodeList.item(i);
  if (childNode.getNodeName() == "person") {
     //do something with it
  }
}

And and I can add more loops to go into subelements, but I would have to know how many nested loops to put in to determine how far into the document to drill. I could nest 10 loops, and end up with a person element nested 12 elements deep in a given document. I need to be able to pull out the element not matter how deeply nested it is.

而且我可以添加更多循环以进入子元素,但我必须知道要放入多少嵌套循环才能确定要钻到文档中的深度。我可以嵌套 10 个循环,最终在给定文档中嵌套了 12 个元素的 person 元素。无论嵌套有多深,我都需要能够拉出元素。

Is there way to harvest elements from an entire document? Like return the text values of all tags as an array or iterate over it?

有没有办法从整个文档中获取元素?喜欢将所有标签的文本值作为数组返回还是迭代它?

Something akin to python's elementtree 'findall' method perhaps:

可能类似于 python 的 elementtree 'findall' 方法:

for person in tree.findall('//person'):
   personlist.append(person)

采纳答案by user125661

As mmyers states, you could use recursion for this problem.

正如 mmyers 所说,您可以对这个问题使用递归。

doSomethingWithAll(root.getChildNodes());

void doSomethingWithAll(NodeList nodeList)
{
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node childNode = nodeList.item(i);
        if (childNode.getNodeName().equals("person")) {
            //do something with it
        }

        NodeList children = childNode.getChildNodes();
        if (children != null)
        {
            doSomethingWithAll(children);
        }
    }
}

回答by kdgregory

That's what XPath is for. To get all elements named "person", here's the expression:

这就是 XPath 的用途。要获取名为“person”的所有元素,请使用以下表达式:

//person

It can be painful to use the JDK's XPath APIs directly. I prefer the wrappers that I wrote in the Practical XML library: http://practicalxml.sourceforge.net/

直接使用 JDK 的 XPath API 可能会很痛苦。我更喜欢我在实用 XML 库中编写的包装器:http: //practicalxml.sourceforge.net/

And here's a tutorial that I wrote (on JDK XPath in general, but mentions XPathWrapper): http://www.kdgregory.com/index.php?page=xml.xpath

这是我写的教程(一般在 JDK XPath 上,但提到 XPathWrapper):http://www.kdgregory.com/index.php?page=xml.xpath

回答by Kathy Van Stone

I see three possiblities (two of which others have answered):

我看到了三种可能性(其他人已经回答了其中两种):

  1. Use recursion.
  2. Use XPath (might be a bit overkill for this problem, but if you have a lot of queries like this it is definitely something to explore). Use kdgregory's help on that; a quick look at the api indicated that it is a bit painful to use directly.
  3. Ifwhat you have is in fact a Document(that is if rootis a Document), you can use Document.getElementsByTagName
  1. 使用递归。
  2. 使用 XPath(对于这个问题可能有点矫枉过正,但如果你有很多这样的查询,它绝对值得探索)。使用 kdgregory 的帮助;快速查看api表明直接使用有点痛苦。
  3. 如果您拥有的实际上是 a Document(即 ifroot是 a Document),则可以使用 Document.getElementsByTagName

回答by Lukas Eder

Apart from Document.getElementsByTagName()or XPath, you could also use jOOX, a library that I have created for simpler XML access and manipulation. jOOX wraps standard Java API's and adds jquery-like utility methods. Your Python code snippet would then translate to this Java code:

除了Document.getElementsByTagName()or XPath,您还可以使用jOOX,这是我为更简单的 XML 访问和操作而创建的库。jOOX 包装了标准的 Java API 并添加了类似jquery的实用方法。然后您的 Python 代码片段将转换为以下 Java 代码:

// Just looking for tag names
for (Element person : $(tree).find("person")) {
  personlist.append(person);
}

// Use XPath for more elaborate queries
for (Element person : $(tree).xpath("//person")) {
  personlist.append(person);
}

回答by parser

Here is the formatted version:

这是格式化的版本:

Element root = xmlData.getDocumentElement();  
NodeList children = root.getChildNodes(); 

public void doSomethingWithAllToConsole(NodeList nodeList, String tabs)
{
    for(int i=0; i<nodeList.getLength(); i++){

      //print current node & values
      Node childNode = nodeList.item(i);
      if(childNode.getNodeType()==Node.ELEMENT_NODE){
          System.out.print(tabs + childNode.getNodeName());
          if(childNode.getFirstChild()!=null 
                  && childNode.getFirstChild().getNodeType()==Node.TEXT_NODE
                  && !StringUtil.isNullOrEmpty(childNode.getFirstChild().getNodeValue()) ){
              System.out.print(" = " + childNode.getFirstChild().getNodeValue());
          }
          System.out.println();
      }

      //recursively iterate through child nodes
      NodeList children = childNode.getChildNodes();
      if (children != null)
      {
          doSomethingWithAllToConsole(children, tabs+"\t");
      }
    }
}