10

我正在使用编码“UTF-8”将对象编组为 XML 文件。它成功生成文件。但是当我尝试将其解组时,出现错误:

在属性“{1}”的值中发现无效的 XML 字符(Unicode:0x{2})并且元素为“0”

字符为 0x1A 或 \u001a,在 UTF-8 中有效,但在 XML 中非法。JAXB 中的 Marshaller 允许将此字符写入 XML 文件,但 Unmarshaller 无法将其解析回来。我尝试使用另一种编码(UTF-16、ASCII 等)但仍然出错。

常见的解决方案是在 XML 解析之前删除/替换这个无效字符。但是如果我们需要这个字符,解组后如何获取原始字符呢?


在寻找此解决方案时,我想在解组之前用替换字符(例如点 =“。”)替换无效字符。

我创建了这个类:

public class InvalidXMLCharacterFilterReader extends FilterReader {

    public static final char substitute = '.'; 

    public InvalidXMLCharacterFilterReader(Reader in) {
        super(in);
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {

        int read = super.read(cbuf, off, len);

        if (read == -1)
            return -1;

        for (int readPos = off; readPos < off + read; readPos++) {
            if(!isValid(cbuf[readPos])) {
                   cbuf[readPos] = substitute;
            }
        }

        return readPos - off + 1; 
    }

    public boolean isValid(char c) {
        if((c == 0x9)
                || (c == 0xA) 
                || (c == 0xD) 
                || ((c >= 0x20) && (c <= 0xD7FF)) 
                || ((c >= 0xE000) && (c <= 0xFFFD)) 
                || ((c >= 0x10000) && (c <= 0x10FFFF)))
        {
            return true;
        } else
            return false;
    }
 }

然后这就是我读取和解组文件的方式:

FileReader fileReader = new FileReader(this.getFile());
Reader reader = new InvalidXMLCharacterFilterReader(fileReader);
Object o = (Object)um.unmarshal(reader);

不知何故,读者不会用我想要的字符替换无效字符。它会导致无法解组的错误 XML 数据。我的 InvalidXMLCharacterFilterReader 类有问题吗?

4

2 回答 2

3

我认为主要问题是在编组期间转义非法字符这里提到了类似的东西,你可以试试。

它提供将编码更改为 Unicodemarshaller.setProperty("jaxb.encoding", "Unicode");

于 2011-04-28T07:41:41.050 回答
3

Unicode 字符 U+001A在 XML 1.0 中是非法的

在这种情况下,用于表示它的编码无关紧要,XML 内容中根本不允许使用它。

XML 1.1 允许包含一些受限字符(包括 U+001A),但它们必须以数字字符引用 ( &#x1a;)的形式出现

维基百科对这种情况做了很好的总结

于 2011-04-28T07:55:41.090 回答