Java中JAXB解析XML丢失注释,还原时位置错位问题求解
问题核心原因
- 现有代码中冗余的
updatedNList逻辑导致插入参考节点计算错误:你手动把待插入的注释先加入临时列表,再取integer+1位置的节点作为插入参考,相当于把参考节点向后偏移了一位,最终导致注释位置错位。 - 你存储注释位置的
commentIntMap如果没有正确记录注释在原始DOM中的真实同级索引,也会直接导致插入位置错误,比如示例中注释在文本节点后方,原始索引应为1,若误存为0就会出现你遇到的前置问题。
解决方案
- 首先修正原始XML解析阶段的索引存储逻辑,确保
commentIntMap中存储的是注释在原始父节点所有子节点(包含文本、注释、元素等所有类型节点)中的真实索引。 - 删除
updateComments方法中冗余的临时列表逻辑,直接基于当前DOM节点的子节点列表计算插入参考节点。
修改后的完整代码
private static void updateComments(final Document document, final Map<String, Comment> commentNodeMap, final Map<String, Node> elementNodeMap, final Map<Comment, Integer> commentIntMap) { // 原有排序逻辑保留,保证先处理上层父节点再处理下层子节点,避免子节点插入影响父节点位置 Set<String> keys = new TreeSet<>(new Comparator<String>() { @Override public int compare(final String s1, final String s2) { if (s1.length() != s2.length()) { return s1.length() - s2.length(); } String[] split1 = s1.split(Constants.COMMENT_SEPARATOR); String[] split2 = s2.split(Constants.COMMENT_SEPARATOR); Integer i1 = Integer.parseInt(split1[0]); Integer i2 = Integer.parseInt(split2[0]); if (((i1 - i2) == 0) && !split1[1].equals(split2[1])) { return split1[1].compareTo(split2[1]); } return i1 - i2; } }); keys.addAll(commentNodeMap.keySet()); for (String exp : keys) { String[] split2 = exp.split(Constants.COMMENT_SEPARATOR); Node parentNode = elementNodeMap.get(split2[1]); if (parentNode != null) { Comment originalComment = commentNodeMap.get(exp); Integer originalIndex = commentIntMap.get(originalComment); if (originalIndex != null) { Comment newComment = document.createComment(originalComment.getData()); NodeList childNodes = parentNode.getChildNodes(); // 直接根据原始索引取参考节点,索引超出当前子节点长度则直接追加到末尾 Node refChild = childNodes.item(originalIndex); if (refChild != null) { parentNode.insertBefore(newComment, refChild); } else { parentNode.appendChild(newComment); } } } } }
修改后即可保证注释位置和原始XML完全一致。
内容的提问来源于stack exchange,提问作者satyam rath
相关产品推荐
相关产品推荐

