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

Java中JAXB解析XML丢失注释,还原时位置错位问题求解

问题核心原因
  • 现有代码中冗余的updatedNList逻辑导致插入参考节点计算错误:你手动把待插入的注释先加入临时列表,再取integer+1位置的节点作为插入参考,相当于把参考节点向后偏移了一位,最终导致注释位置错位。
  • 你存储注释位置的commentIntMap如果没有正确记录注释在原始DOM中的真实同级索引,也会直接导致插入位置错误,比如示例中注释在文本节点后方,原始索引应为1,若误存为0就会出现你遇到的前置问题。
解决方案
  1. 首先修正原始XML解析阶段的索引存储逻辑,确保commentIntMap中存储的是注释在原始父节点所有子节点(包含文本、注释、元素等所有类型节点)中的真实索引。
  2. 删除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:24:04