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

如何通过JAXB生成无父元素的交替重复XML元素?

解决JAXB生成交替无父节点的XML元素问题

我之前对接第三方系统时也碰到过一模一样的需求,要生成这种交替排列、没有中间父元素包裹的XML结构,用JAXB其实可以通过组合注解轻松实现,下面是具体的落地方案:

1. 定义单个元素的实体类

首先给<code>和<percentage>分别创建简单的实体类,用@XmlRootElement指定对应XML元素名,@XmlValue绑定元素的文本内容:

Code类

@XmlRootElement(name = "code")
public class Code {
    private String value;

    // JAXB强制要求无参构造器
    public Code() {}

    public Code(String value) {
        this.value = value;
    }

    @XmlValue
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

Percentage类

@XmlRootElement(name = "percentage")
public class Percentage {
    private int value;

    public Percentage() {}

    public Percentage(int value) {
        this.value = value;
    }

    @XmlValue
    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

2. 定义Education父节点类

核心逻辑就在这个类的注解上,我们用@XmlMixed + @XmlAnyElement(lax = true)组合,让列表中的元素直接成为<education>的子节点,不需要额外的包裹元素:

@XmlRootElement(name = "education")
public class Education {
    private List<Object> elements = new ArrayList<>();

    @XmlMixed
    @XmlAnyElement(lax = true)
    public List<Object> getElements() {
        return elements;
    }

    public void setElements(List<Object> elements) {
        this.elements = elements;
    }

    // 封装工具方法,方便按顺序添加元素
    public void addCode(String code) {
        elements.add(new Code(code));
    }

    public void addPercentage(int percent) {
        elements.add(new Percentage(percent));
    }
}

这里的注解作用说明:

  • @XmlMixed:允许父节点下混合文本和子元素,这里我们用它来取消JAXB默认给列表添加的包裹元素
  • @XmlAnyElement(lax = true):开启宽松模式后,JAXB会识别列表中带有@XmlRootElement的实体类,将它们序列化为对应的XML元素,而不是当作未知元素处理

3. 测试序列化效果

写个简单的测试代码验证生成的XML结构:

public class JaxbTest {
    public static void main(String[] args) throws JAXBException {
        Education education = new Education();
        // 按需求的交替顺序添加元素
        education.addCode("ENG24");
        education.addPercentage(25);
        education.addCode("ENG25");
        education.addPercentage(20);
        education.addCode("SPA50");
        education.addPercentage(30);

        // 初始化JAXB上下文,必须包含所有相关实体类
        JAXBContext context = JAXBContext.newInstance(Education.class, Code.class, Percentage.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        // 输出格式化后的XML
        marshaller.marshal(education, System.out);
    }
}

运行后生成的XML完全符合第三方要求:

<education>
    <code>ENG24</code>
    <percentage>25</percentage>
    <code>ENG25</code>
    <percentage>20</percentage>
    <code>SPA50</code>
    <percentage>30</percentage>
</education>

额外注意点

  • 创建JAXBContext时一定要传入所有用到的实体类,或者使用包路径扫描的方式,否则JAXB无法识别这些类对应的XML元素
  • 如果需要反序列化这种结构,同样可以用这套方案,JAXB会自动把交替的元素映射回列表中的对应实体对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:03:42