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

Java中XML注释与处理指令的检测/移除及冗余空格去除方案

Java中高效处理XML注释与处理指令的两种场景方案

场景一:检测到注释/处理指令则终止处理,否则移除冗余空格

要实现这个需求,最高效的方式是采用SAX流式解析——它不需要加载整个XML到内存,适合处理大文件,且能在解析过程中实时检测注释和处理指令。

1. 实现检测逻辑

自定义SAX处理器,重写注释和处理指令的回调方法,一旦触发就抛出异常终止处理:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XmlValidationHandler extends DefaultHandler {
    // 检测到注释则抛出异常
    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {
        throw new SAXException("XML包含注释,处理终止");
    }

    // 检测到处理指令则抛出异常
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        throw new SAXException("XML包含处理指令,处理终止");
    }
}

2. 执行检测

通过SAXParser加载自定义处理器完成验证:

import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;

public class XmlValidator {
    public static void validateNoCommentsOrPIs(File xmlFile) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        SAXParser parser = factory.newSAXParser();
        parser.parse(xmlFile, new XmlValidationHandler());
    }
}

3. 验证通过后移除冗余空格

使用JDK自带的Transformer完成空格压缩,仅保留文本内容中必要的空格:

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;

public class XmlSpaceCompressor {
    public static void compressRedundantSpaces(File input, File output) throws Exception {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        // 关闭缩进,移除冗余空格
        transformer.setOutputProperty("indent", "no");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "0");
        transformer.transform(new StreamSource(input), new StreamResult(output));
    }
}

4. 组合调用

public class Main {
    public static void main(String[] args) {
        File input = new File("source.xml");
        File output = new File("compressed.xml");
        
        try {
            // 先执行检测
            XmlValidator.validateNoCommentsOrPIs(input);
            // 检测通过后压缩空格
            XmlSpaceCompressor.compressRedundantSpaces(input, output);
            System.out.println("处理成功");
        } catch (SAXException e) {
            System.err.println("处理失败:" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

场景二:移除注释与处理指令,同时压缩冗余空格

同样采用SAX流式解析,在解析过程中跳过注释和处理指令,同时构建清理后的XML文档,全程无需加载完整XML,效率最优。

1. 实现清理逻辑

自定义SAX处理器,结合TransformerHandler直接输出清理后的XML,跳过注释和处理指令,同时压缩文本中的冗余空格:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

public class XmlCleanerHandler extends DefaultHandler {
    private TransformerHandler transformerHandler;

    public XmlCleanerHandler(StreamResult result) throws Exception {
        SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();
        transformerHandler = factory.newTransformerHandler();
        Transformer transformer = transformerHandler.getTransformer();
        // 关闭缩进,压缩空格
        transformer.setOutputProperty("indent", "no");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "0");
        transformerHandler.setResult(result);
        transformerHandler.startDocument();
    }

    // 转发元素开始事件
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        transformerHandler.startElement(uri, localName, qName, attributes);
    }

    // 转发元素结束事件
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        transformerHandler.endElement(uri, localName, qName);
    }

    // 压缩文本中的冗余空格,仅保留非空文本
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        String text = new String(ch, start, length).trim();
        if (!text.isEmpty()) {
            transformerHandler.characters(text.toCharArray(), 0, text.length());
        }
    }

    // 跳过注释
    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {
        // 无操作,直接跳过
    }

    // 跳过处理指令
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        // 无操作,直接跳过
    }

    // 结束文档
    @Override
    public void endDocument() throws SAXException {
        transformerHandler.endDocument();
    }
}

2. 执行清理

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileOutputStream;

public class XmlCleaner {
    public static void cleanXml(File input, File output) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        SAXParser parser = factory.newSAXParser();

        try (FileOutputStream fos = new FileOutputStream(output)) {
            StreamResult result = new StreamResult(fos);
            XmlCleanerHandler handler = new XmlCleanerHandler(result);
            parser.parse(input, handler);
        }
    }
}

3. 调用示例

public class Main {
    public static void main(String[] args) {
        File input = new File("source.xml");
        File output = new File("cleaned.xml");
        
        try {
            XmlCleaner.cleanXml(input, output);
            System.out.println("XML清理完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:24:39