【问题标题】:Invalid XML Character During Unmarshall解组期间 XML 字符无效
【发布时间】:2011-04-28 07:24:52
【问题描述】:

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

无效的 XML 字符(Unicode: 0x{2}) 的值中发现 属性“{1}”且元素为“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 类有问题吗?

【问题讨论】:

  • 能否请您检查 XML 标头,编组后在其中定义了哪个字符集?是 UTF-8 吗?
  • XML 标头中没有定义字符集,只有 。但我已经把这个:m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

标签: java xml-serialization jaxb unmarshalling


【解决方案1】:

我认为主要问题是关于在编组过程中转义非法字符here提到了类似的东西,你可以试试。

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

【讨论】:

  • 我试图在编组过程中转义非法字符,正如那里提到的那样,将字符“0x1a”转换为字符引用“$#x1a;”并将编码更改为“Unicode”,但在解组过程中仍然出现错误:字符引用“”是无效的 XML 字符。
【解决方案2】:

Unicode 字符 U+001A 是illegal in XML 1.0

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

XML 1.1 allows some of the restricted characters(包括 U+001A)将被包括在内,但它们必须以数字字符引用的形式出现 (&amp;#x1a;)

维基百科有a nice summary of the situation

【讨论】:

  • 您知道如何将 Marshaller 属性设置为具有 XML 1.1 标头吗?我试过这个但没有用:m.setProperty("com.sun.xml.bind.xmlHeaders", "&lt;?xml version=\"1.1\"?&gt;");
  • 看起来 JAXB 还不支持 XML 1.1:java.net/jira/browse/JAXB-422
  • 我认为违规字符不是 0x02,请注意 {2} 和 {1} 周围的花括号,这看起来更像是错误消息中的占位符没有被替换。
  • @Jörn:你说得对,U+001A 似乎是问题所在,但那个角色也有同样的问题。
  • 可以用其他XML序列化API处理吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
相关资源
最近更新 更多