如何在JAXB反序列化时保留XML中兄弟标签的原始顺序
如何在JAXB反序列化时保留XML中兄弟标签的原始顺序
这个问题我之前踩过同款坑!JAXB默认会按元素类型批量收集节点,所以才会把所有<BatchHeader>堆在一起,接着是所有<Entry>,完全打乱了你原来的分组顺序。不过真的不用手动拼XML遭罪,有个很靠谱的方案解决这个问题。
核心思路是:不要把不同类型的节点分开存成独立List,而是用一个统一的列表来容纳所有中间节点,让JAXB按原始顺序逐个加入。具体做法是用@XmlElements注解来指定每个XML元素对应的Java类型,这样JAXB就会乖乖按XML里的顺序把元素塞进列表里了。
给你修改后的Transactions类代码,亲测有效:
@Getter @Setter @XmlRootElement(name = "Transactions") @XmlAccessorType(XmlAccessType.FIELD) public class Transactions { @XmlElement(name = "FileHeader") private FileHeader fileHeader; // 统一列表,按XML原始顺序存放所有中间节点 @XmlElements({ @XmlElement(name = "BatchHeader", type = BatchHeader.class), @XmlElement(name = "Entry", type = Entry.class), @XmlElement(name = "Addenda", type = Addenda.class), @XmlElement(name = "BatchControl", type = BatchControl.class) }) private List<Object> transactionElements; @XmlElement(name = "FileControl") private FileControl fileControl; }
这样配置后,反序列化时JAXB会严格按照XML里元素出现的先后顺序,把每个元素依次加入transactionElements列表。比如第一个<BatchHeader>是列表的第一个元素,接着是它对应的<Entry>、<Addenda>、<BatchControl>,然后是第二个<BatchHeader>,完全和原始XML的顺序一致。
如果之后需要把这些零散的元素重新组装成逻辑上的Batch分组(比如把每个<BatchHeader>到对应的<BatchControl>之间的元素归为一组),可以自己写个简单的组装方法,比如:
// 假设你有一个Batch类,用来封装一组Batch相关的元素 public class Batch { private BatchHeader batchHeader; private List<Entry> entries = new ArrayList<>(); private List<Addenda> addendas = new ArrayList<>(); private BatchControl batchControl; // 这里省略Getter和Setter } // 在Transactions类里添加组装方法 public List<Batch> assembleBatches() { List<Batch> batches = new ArrayList<>(); Batch currentBatch = null; for (Object element : transactionElements) { if (element instanceof BatchHeader) { // 遇到新的BatchHeader,创建新的Batch对象 currentBatch = new Batch(); currentBatch.setBatchHeader((BatchHeader) element); batches.add(currentBatch); } else if (element instanceof Entry && currentBatch != null) { currentBatch.getEntries().add((Entry) element); } else if (element instanceof Addenda && currentBatch != null) { currentBatch.getAddendas().add((Addenda) element); } else if (element instanceof BatchControl && currentBatch != null) { currentBatch.setBatchControl((BatchControl) element); } } return batches; }
这样一来,既用JAXB完成了反序列化,又完美保留了原始XML的顺序,还能方便地把元素组装成你需要的业务结构,比手动拼XML高效太多啦。
备注:内容来源于stack exchange,提问作者ShahriyarHossain
相关产品推荐
相关产品推荐

