首页 > 解决方案 > 名称包含中文字符时的异常 XML 实体 - 如何解码?

问题描述

当文件名包含中文字符时,我有一个使用异常实体的 XML。我不知道如何解码这些文件名。有任何想法吗?

<string name="Name" value="&Aacute;&yacute;&frac34;&micro; &ordm;&pound;&Iacute;&otilde;&Ocirc;&curren;&cedil;&aelig;&AElig;&not;-01.wav"/>

结果名称应该是慢镜海王预告片-01.wav

我如何将这些改回正确的名称?

标签: javaxmlcjk

解决方案


看起来以 GB18030 编码编码的文本已被解释为 Latin-1,然后字符已被转义为 HTML 实体引用。

Apache Commons Text中类的unescapeHtml4()方法可以用来对实体引用进行转义,下面的小程序演示了这一点。StringEscapeUtils

笼镜 海王预告片-01.wav打印到标准输出。这与您要求的非常相似。只有第一个汉字不同。如果&Aacute;在输入字符串中更改为&Acirc;,则程序输出所需的确切文件名 ( 慢镜 海王预告片-01.wav)。

import java.nio.charset.Charset;
import java.io.PrintStream;
import org.apache.commons.text.StringEscapeUtils;

public class Chinese {
    public static void main(String[] args) {
        String fname = "&Aacute;&yacute;&frac34;&micro; &ordm;&pound;&Iacute;&otilde;&Ocirc;&curren;&cedil;&aelig;&AElig;&not;-01.wav";
        decode(fname);
    }

    static void decode(String s) {
        Charset latin1 = Charset.forName("latin1");
        Charset gb18030 = Charset.forName("gb18030");
        Charset utf8 = Charset.forName("utf8");

        String unescaped = StringEscapeUtils.unescapeHtml4(s);
        byte[] latin1_bytes = unescaped.getBytes(latin1);
        String text = new String(latin1_bytes, gb18030);

        PrintStream ps = new PrintStream(System.out, true, utf8);
        ps.println(text);
    }
}

推荐阅读