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

Java如何批量将XML文件中的十六进制字符实体转为对应字符

Java实现XML十六进制字符实体转原生字符方案

需求背景

  • 待处理大型XML文件中存在大量十六进制格式的XML字符实体,格式为&#x十六进制码点;,例如§对应原生字符§
  • 待处理内容示例:
<md.first.line.cite>UT ST &#xA7;&#x2002;10-2-409</md.first.line.cite>
  • 要求转换后实体替换为对应原生字符,同时适配大文件场景,避免内存溢出。

方案1:原生JDK流式正则替换(无额外依赖,适合超大文件)

核心逻辑是逐行/逐块读取文件,通过正则匹配实体后解析码点替换为对应字符,全程内存仅占用单块读取的缓冲区大小,不会出现大文件OOM问题。

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HexXmlEntityConverter {
    // 匹配十六进制XML字符实体,捕获组提取十六进制码点
    private static final Pattern HEX_ENTITY_PATTERN = Pattern.compile("&#x([0-9a-fA-F]+);");

    public static void convert(String inputPath, String outputPath) throws IOException {
        // 采用带缓冲区的字符流逐行读写,默认8KB缓冲区,内存占用极低
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(new FileInputStream(inputPath), StandardCharsets.UTF_8));
             BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(outputPath), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(replaceHexEntity(line));
                writer.newLine();
            }
        }
    }

    private static String replaceHexEntity(String content) {
        Matcher matcher = HEX_ENTITY_PATTERN.matcher(content);
        StringBuilder result = new StringBuilder();
        while (matcher.find()) {
            // 解析十六进制码点
            int codePoint = Integer.parseInt(matcher.group(1), 16);
            // 兼容Unicode增补平面字符(如生僻字、emoji),正确处理代理对
            matcher.appendReplacement(result, Matcher.quoteReplacement(new String(Character.toChars(codePoint))));
        }
        matcher.appendTail(result);
        return result.toString();
    }

    public static void main(String[] args) throws IOException {
        convert("your_input.xml", "your_output.xml");
    }
}

注意事项

  • 如果XML存在单行内容过大的情况,可以把逐行读取改成固定大小字符块读取,替换逻辑和上述代码一致
  • 用Character.toChars(codePoint)处理码点,能正确识别Unicode增补平面字符,不会出现乱码

方案2:基于Apache Commons Text实现(项目已有依赖可直接用)

如果项目中已经引入Apache Commons Text依赖,可以直接使用内置的XML实体解码工具,不需要自己写正则逻辑,读写逻辑和方案1一致,仅替换实体转换的方法即可:

import org.apache.commons.text.StringEscapeUtils;

private static String replaceHexEntity(String content) {
    // 自动解码所有XML实体,包括十六进制实体、十进制实体、XML内置实体(如&amp;、&lt;等)
    return StringEscapeUtils.unescapeXml(content);
}

注意:不要使用旧版commons-lang包中的StringEscapeUtils,该版本对Unicode增补平面字符的处理存在bug,会导致乱码,请使用commons-text包下的对应方法。

转换效果验证

示例内容转换后输出为:

<md.first.line.cite>UT ST § 10-2-409</md.first.line.cite>

其中&#xA7;转换为分节符§,&#x2002;转换为对应宽度的空格,符合预期。

内容的提问来源于stack exchange,提问作者Suprita S B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:15:35