You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将带递归子节点结构的XML转换为Java对象?

这问题挺典型的,嵌套递归的XML转Java对象,核心就是把这种递归结构映射成对应的递归Java类,我给你一步步捋清楚:

1. 定义匹配递归结构的Java实体类

首先得对应XML的层级和递归关系来写类:

  • <template> 对应根类 Template,里面包含一个顶级的 Condition
  • <condition> 对应 Condition 类:有name属性,必须包含Li标签,所以要定义一个非空的List<Li>
  • <li> 对应 Li 类:可选value属性,可选的文本内容(比如<li value="BB">Value B</li>里的文本),还可以嵌套一个Condition(因为部分Li里会有子Condition)

用JAXB注解的实体类(Java自带,无需额外依赖)

import javax.xml.bind.annotation.*;
import java.util.List;

@XmlRootElement(name = "template")
@XmlAccessorType(XmlAccessType.FIELD)
public class Template {
    @XmlElement(name = "condition")
    private Condition condition;

    // Getters and Setters
    public Condition getCondition() { return condition; }
    public void setCondition(Condition condition) { this.condition = condition; }
}

@XmlAccessorType(XmlAccessType.FIELD)
public class Condition {
    @XmlAttribute(name = "name")
    private String name;

    @XmlElement(name = "li")
    private List<Li> liList; // 必须包含Li,所以这个list不能为null/空

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public List<Li> getLiList() { return liList; }
    public void setLiList(List<Li> liList) { this.liList = liList; }
}

@XmlAccessorType(XmlAccessType.FIELD)
public class Li {
    @XmlAttribute(name = "value")
    private String value;

    @XmlValue
    private String textContent; // 对应<li>里的文本内容,比如"Value B"

    @XmlElement(name = "condition")
    private Condition nestedCondition; // 嵌套的子Condition,可选

    // Getters and Setters
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }
    public String getTextContent() { return textContent; }
    public void setTextContent(String textContent) { this.textContent = textContent; }
    public Condition getNestedCondition() { return nestedCondition; }
    public void setNestedCondition(Condition nestedCondition) { this.nestedCondition = nestedCondition; }
}

用Jackson XML注解的实体类(更灵活,适合复杂场景)

如果你用Jackson来处理,需要先引入jackson-dataformat-xml依赖,实体类注解如下:

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;

@JacksonXmlRootElement(localName = "template")
public class Template {
    @JacksonXmlProperty(localName = "condition")
    private Condition condition;

    // Getters and Setters
    public Condition getCondition() { return condition; }
    public void setCondition(Condition condition) { this.condition = condition; }
}

public class Condition {
    @JacksonXmlProperty(isAttribute = true)
    private String name;

    @JacksonXmlProperty(localName = "li")
    private List<Li> liList;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public List<Li> getLiList() { return liList; }
    public void setLiList(List<Li> liList) { this.liList = liList; }
}

public class Li {
    @JacksonXmlProperty(isAttribute = true)
    private String value;

    @JacksonXmlProperty(isAttribute = false)
    private String textContent;

    @JacksonXmlProperty(localName = "condition")
    private Condition nestedCondition;

    // Getters and Setters
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }
    public String getTextContent() { return textContent; }
    public void setTextContent(String textContent) { this.textContent = textContent; }
    public Condition getNestedCondition() { return nestedCondition; }
    public void setNestedCondition(Condition nestedCondition) { this.nestedCondition = nestedCondition; }
}
2. 解析XML为Java对象的示例代码

用JAXB解析(Java自带)

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;

public class XmlParser {
    public static void main(String[] args) throws Exception {
        String xmlContent = """
                <template>
                  <condition name="A">
                    <li value="A">
                      <condition name="B">
                        <li value="BB">Value B</li>
                        <li value="BBB">Value BBB</li>
                      </condition>
                    </li>
                    <li>
                      <condition name="C">
                        <li value="CC">Value CC</li>
                        <li value="CCC">Value CCC</li>
                        <li>
                          <condition name="D">
                            <li value="DD">Value DD</li>
                            <li value="DDD">Value DDD</li>
                          </condition>
                        </li>
                      </condition>
                    </li>
                  </condition>
                </template>
                """;

        JAXBContext jaxbContext = JAXBContext.newInstance(Template.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        Template template = (Template) unmarshaller.unmarshal(new StringReader(xmlContent));

        // 验证解析结果,比如打印顶级Condition的name
        System.out.println("Top condition name: " + template.getCondition().getName());
    }
}

用Jackson XML解析

import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class JacksonXmlParser {
    public static void main(String[] args) throws Exception {
        String xmlContent = """
                <template>
                  <condition name="A">
                    <li value="A">
                      <condition name="B">
                        <li value="BB">Value B</li>
                        <li value="BBB">Value BBB</li>
                      </condition>
                    </li>
                    <li>
                      <condition name="C">
                        <li value="CC">Value CC</li>
                        <li value="CCC">Value CCC</li>
                        <li>
                          <condition name="D">
                            <li value="DD">Value DD</li>
                            <li value="DDD">Value DDD</li>
                          </condition>
                        </li>
                      </condition>
                    </li>
                  </condition>
                </template>
                """;

        XmlMapper xmlMapper = new XmlMapper();
        Template template = xmlMapper.readValue(xmlContent, Template.class);

        System.out.println("Top condition name: " + template.getCondition().getName());
    }
}
3. 额外注意点
  • 因为要求Condition标签必须包含Li标签,可以在实体类里添加校验逻辑,比如用JSR-380的@NotNull和@NotEmpty注解,或者在解析完成后手动检查Condition.getLiList()是否为空。
  • 如果XML里的<li>既有文本内容又有嵌套Condition,要确保注解能正确识别,JAXB的@XmlValue可以处理文本内容,Jackson也能自动映射(注意属性和文本的优先级)。

内容的提问来源于stack exchange,提问作者Joseph Move

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:58:17