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

如何用Java的JAXB将嵌套XML的Address拆分至多个Account标签

问题与解决方案

问题说明

原始XML响应

<RootElement>
    <Account>
     <Address>
      <Name>xyz</Name>
     </Address>
     <Address>
      <Name>abc</Name>
     </Address>
    </Account>
    <Account>
     <Address>
      <Name>def</Name>
     </Address>
     <Address>
      <Name>pqr</Name>
     </Address>
   </Account>
</RootElement>

现有Java实体类

@XmlRootElement(name="RootElement")
class RootElement {
  
  @XmlElement(name="Account")
  List<Account> account;

//corresponding getter and setter method
}
@XmlRootElement(name="Account")
class Account {

 @XmlElement(name="Address")
 List<Address> address;

//corresponding getter and setter method
}
@XmlRootElement(name="Address")
class Address {

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

//corresponding getter and setter method

}

目标XML结构

<RootElement>
    <Account>
     <Address>
      <Name>xyz</Name>
     </Address>
    </Account>
    <Account>
     <Address>
      <Name>abc</Name>
     </Address>
    </Account>
    <Account>
     <Address>
      <Name>def</Name>
     </Address>
   </Account>
   <Account>
     <Address>
      <Name>pqr</Name>
     </Address>
   </Account>
</RootElement>

当前编组代码

JAXBContext context = JAXBContext.newInstance(CreateExemptionCertificate.class);
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    StringWriter sw = new StringWriter();
    m.marshal(cc, sw);

    String result = sw.toString();

问题核心:需要将原始XML中每个<Account>下的多个<Address>拆分为独立的<Account>标签,每个<Account>仅包含一个<Address>。

解决方案

1. 数据结构转换(关键步骤)

在编组前,先将原始的RootElement对象转换为目标结构:遍历每个原始Account下的所有Address,为每个Address单独创建一个新的Account对象,最终组成新的Account列表。

代码示例:

// 假设originalRoot是解析原始XML得到的RootElement对象
List<Account> targetAccounts = new ArrayList<>();

for (Account originalAccount : originalRoot.getAccount()) {
    // 遍历当前Account下的每个Address
    for (Address addr : originalAccount.getAddress()) {
        Account newAccount = new Account();
        List<Address> singleAddrList = new ArrayList<>();
        singleAddrList.add(addr);
        newAccount.setAddress(singleAddrList);
        targetAccounts.add(newAccount);
    }
}

// 创建新的RootElement对象用于编组
RootElement targetRoot = new RootElement();
targetRoot.setAccount(targetAccounts);

2. 确认JAXB注解有效性

现有实体类的注解完全符合目标XML的要求:

  • RootElement类的@XmlElement(name="Account")会将列表中的每个Account实例生成为独立的<Account>标签
  • Account类的@XmlElement(name="Address")会将列表中的单个Address生成为<Address>标签

3. 修改编组代码

将编组时传入的对象替换为转换后的targetRoot,同时修正JAXBContext的实例化类(应为RootElement.class):

JAXBContext context = JAXBContext.newInstance(RootElement.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
StringWriter sw = new StringWriter();
m.marshal(targetRoot, sw); // 传入转换后的RootElement对象
String result = sw.toString();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:30:53