如何用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
相关产品推荐
相关产品推荐

