如何使用JAXB将含diffgr标签的XML字符串反序列化为Java POJO
问题核心原因
你的代码存在两处核心错误导致匹配失败:
- 层级结构不匹配:XML为嵌套结构,
<Result>下仅包含<diffgr:diffgram>子节点,<NewDataSet>是diffgram的子节点,<DT1>又是NewDataSet的子节点,你将三个属性都定义在Response同一层级,自然无法匹配到节点。 - 命名空间处理错误:
diffgr是命名空间前缀,对应的完整命名空间为urn:schemas-microsoft-com:xml-diffgram-v1,不能直接将前缀写在@XmlElement的name属性中,需要单独指定namespace参数。
正确实现代码
1. 按XML嵌套结构定义POJO
import javax.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; // 根节点Result @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Result") public class Response { @XmlElement(name = "diffgram", namespace = "urn:schemas-microsoft-com:xml-diffgram-v1") private Diffgram diffgram; public Diffgram getDiffgram() { return diffgram; } public void setDiffgram(Diffgram diffgram) { this.diffgram = diffgram; } // Diffgram节点类 @XmlAccessorType(XmlAccessType.FIELD) public static class Diffgram { @XmlElement(name = "NewDataSet") private NewDataSet newDataSet; public NewDataSet getNewDataSet() { return newDataSet; } public void setNewDataSet(NewDataSet newDataSet) { this.newDataSet = newDataSet; } } // NewDataSet节点类 @XmlAccessorType(XmlAccessType.FIELD) public static class NewDataSet { @XmlElement(name = "DT1") private List<DT> dtList; public List<DT> getDtList() { if (dtList == null) { dtList = new ArrayList<>(); } return dtList; } public void setDtList(List<DT> dtList) { this.dtList = dtList; } } // DT1节点类 @XmlAccessorType(XmlAccessType.FIELD) public static class DT { @XmlElement(name = "TEST_NO") private String testNo; @XmlElement(name = "TEST_DESC") private String testDesc; public String getTestNo() { return testNo; } public void setTestNo(String testNo) { this.testNo = testNo; } public String getTestDesc() { return testDesc; } public void setTestDesc(String testDesc) { this.testDesc = testDesc; } @Override public String toString() { return "DT{" + "testNo='" + testNo + '\'' + ", testDesc='" + testDesc + '\'' + '}'; } } }
2. 反序列化测试代码
JAXBContext jaxbContext = JAXBContext.newInstance(Response.class); Unmarshaller jaxbUnMarshaller = jaxbContext.createUnmarshaller(); Response response = (Response)jaxbUnMarshaller.unmarshal(new StringReader(xml)); // 直接获取DT列表 List<Response.DT> dtList = response.getDiffgram().getNewDataSet().getDtList(); // 输出验证 dtList.forEach(System.out::println);
如果不需要保留diffgram、NewDataSet两层冗余包装,也可以在反序列化前通过StAX解析器过滤外层节点,直接从<NewDataSet>节点开始反序列化,减少不必要的类定义。
内容的提问来源于stack exchange,提问作者Ye.s
相关产品推荐
相关产品推荐

