如何循环遍历 JAXB 类,如果同一 XML 节点不止一层

How to Loop through JAXB classes, if there are more than one level of same XML node

这是我实际 XML 的最漂亮版本(我没有 XSD,也不会从源系统中获得它)

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <!--Java Class Comp.java-->
  <Comp>
    <Name>Component Name</Name>
    <Available_Start_Date>2018-07-10</Available_Start_Date>
 <!--Java Class P_to_P.java-->
    <P_to_P>
      <Max>1</Max>
      <Min>1</Min>
   <!-- Java Class P.java-->
      <P>
        <Name>Composite</Name>
        <P_to_P>
          <Max>1</Max>
          <Min>1</Min>
          <P>
            <Name>Another Level</Name>
          </P>
        </P_to_P>
        <P_to_P>
          <Max>1</Max>
          <Min>1</Min>
          <P>
            <Name>Yet Another Level</Name>
          </P>
        </P_to_P>
      </P>
    </P_to_P>
  </Comp>
</Root>

现在,如果我开始为其编写 JAXB 类(手动并使用 IDE),我必须为我正在经历的每个级别编写 for 循环。现在,这个 XML 中的 child 可能显示为 child 的 Parent(P_to_P 有 P 作为 child 而 P 有 P_to_P 为 child,并且 parent-child 关系的深度可以是任意数量的级别。

因此,如果我编写一个 Main JAXB 文件,那么我是否必须在 for 循环中编写那么多 for 循环以遍历所有 Parent 和 Child?还是有更好的方法来实现?

您可以像这样编写您的 POJO 类 PP_to_P

@XmlAccessorType(XmlAccessType.FIELD)
public class P_to_P {

    @XmlElement(name = "Max")
    private int max;

    @XmlElement(name = "Min")
    private int min;

    @XmlElement(name = "P")
    private P p;

    // public getters and setters (omitted for brevity)
}

@XmlAccessorType(XmlAccessType.FIELD)
public class P {

    @XmlElement(name = "Name")
    private String name;

    @XmlElement(name = "P_to_P")
    private List<P_to_P> pToPList;

    // public getters and setters (omitted for brevity)
}

然后你能遍历整个树并像下面这样处理每个项目吗?
注意递归:方法 process(P_to_P) 调用 process(P), 方法 process(P) 调用 process(P_to_P)。 还要注意检查 null 以防止 NullPointerException 并终止递归。

public static void main(String[] args) {
    File file = new File("root.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
    Unmarshaller unmarshaller = jaxbCntext.createUnmarshaller();
    Root root = (Root) unmarshaller.unmarshal(file);

    P_to_P pToP = root.getComp().getPToP();
    process(pToP);
}

private static void process(P_to_P pToP) {
   if (pToP == null)
       return;

   // do anything you like here

   process(pToP.getP());
}

private static void process(P p) {
   if (p == null)
       return;

   // do anything you like here

   if (p.getpToPList() == null)
       return;
   for (P_to_P pToP : p.getpToPList()) {
       process(pToP);
   }
}