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

如何美化XML:属性换行、闭合标签修正及保留注释

可行的XML美化方案

一、自定义Java格式化逻辑(结合DOM解析)

既然现有工具没法同时满足所有需求,自己基于DOM API实现格式化是最可控的方案,能精准适配你的格式要求还保留注释:

  1. 开启注释保留的XML解析:
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setIgnoringComments(false); // 关键配置:不忽略注释
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(new File("你的输入XML路径"));
    
  2. 递归遍历节点生成格式化文本:
    核心逻辑分几个关键点:
    • 注释节点直接按缩进输出,不做修改
    • 元素节点判断属性数量:单属性和标签同行,多属性每个单独换行并对齐缩进
    • 空内容标签直接输出自闭合形式,替代冗余的<tag></tag>
  3. 核心逻辑片段示例:
    private void formatNode(Node node, int indent, StringBuilder sb) {
        // 处理注释节点
        if (node instanceof Comment) {
            sb.append(getIndent(indent)).append("<!--").append(node.getTextContent()).append("-->\n");
            return;
        }
        if (!(node instanceof Element)) return;
        Element elem = (Element) node;
        sb.append(getIndent(indent)).append("<").append(elem.getTagName());
        NamedNodeMap attrs = elem.getAttributes();
        int attrCount = attrs.getLength();
        // 处理属性
        if (attrCount > 0) {
            if (attrCount == 1) {
                Node attr = attrs.item(0);
                sb.append(" ").append(attr.getNodeName()).append("=\"").append(attr.getNodeValue()).append("\"");
            } else {
                sb.append("\n");
                for (int i = 0; i < attrCount; i++) {
                    Node attr = attrs.item(i);
                    sb.append(getIndent(indent + 1))
                      .append(attr.getNodeName()).append("=\"").append(attr.getNodeValue()).append("\"\n");
                }
                sb.append(getIndent(indent));
            }
        }
        // 判断是否为空内容标签
        boolean isEmpty = elem.getChildNodes().getLength() == 0 || 
            (elem.getChildNodes().getLength() == 1 && elem.getFirstChild() instanceof Text && 
            ((Text)elem.getFirstChild()).getTextContent().trim().isEmpty());
        if (isEmpty) {
            sb.append("/>\n");
        } else {
            sb.append(">\n");
            NodeList children = elem.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                formatNode(children.item(i), indent + 1, sb);
            }
            sb.append(getIndent(indent)).append("</").append(elem.getTagName()).append(">\n");
        }
    }
    // 生成缩进字符串,可自定义空格数
    private String getIndent(int level) {
        return "    ".repeat(level);
    }
    

二、字符串层面正则修正(适合简单场景)

如果不想写复杂的DOM逻辑,正则可以临时解决问题,但注意仅适合结构简单、无特殊字符(比如属性值含</>)的XML:

  1. 替换空闭合标签为自闭合标签:
    // 避开注释内的内容,匹配纯空标签
    String regex = "(?<!<!--.*)<([a-zA-Z0-9_-]+)(\\s+[^>]*)?></\\1>(?!.*-->)";
    String formattedXml = rawXml.replaceAll(regex, "<$1$2/>");
    
  2. 调整属性换行格式:
    // 处理单属性同行、多属性换行
    formattedXml = formattedXml.replaceAll("<([a-zA-Z0-9_-]+)\\s+([^>]+?)>", m -> {
        String tag = m.group(1);
        String attrs = m.group(2);
        String[] attrArr = attrs.split("\\s+(?=[a-zA-Z0-9_-]+=)");
        if (attrArr.length == 1) {
            return "<" + tag + " " + attrs + ">";
        } else {
            StringBuilder sb = new StringBuilder("<" + tag + "\n");
            for (String attr : attrArr) {
                sb.append("    ").append(attr).append("\n");
            }
            sb.append(">");
            return sb.toString();
        }
    });
    

三、第三方库:Jackson XML(需自定义序列化)

Jackson XML可以通过配置和自定义序列化器实现需求,稳定性更高:

  1. 添加依赖:
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.15.2</version>
    </dependency>
    
  2. 基础配置+自定义序列化:
    XmlMapper mapper = new XmlMapper();
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    // 开启空标签自闭合
    mapper.configure(ToXmlGenerator.Feature.WRITE_XML_EMPTY_ELEMENTS_AS_EMPTY_TAGS, false);
    // 要实现单属性同行、多属性换行,需要自定义XmlSerializer扩展类,重写属性序列化逻辑
    

这个方案需要额外写自定义序列化器,但胜在能处理复杂XML场景,且维护性强。

内容的提问来源于stack exchange,提问作者TenderDen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:15:36