java - 使用 XMLScanner 反序列化 xml 导致输出字符串更大

标签 java xml jaxb stax woodstox

我们的产品升级过程包括将旧模式数据库导出到文件(JAXB 序列化),然后导入到新模式(StAX + JAXB)。有时,升级会由于超过其最大大小的值引起的插入错误而失败,尽管它们之前是从同一数据库表导出的。

当反序列化 xml 时会发生这种情况(在本例中使用 Jaxb,但它不仅仅与 Jaxb 相关),并且其中一个属性具有高代理 UTF-8 字符序列的值,SAX 解析器存在错误,导致输出字符串更大:

3 个字符 -> (1+2+3=) 6 个字符。
6 个字符 -> (1+2+3+4+5+6=) 21 个字符。
(源字符的算术级数)

代码来自 java 1.7_45 代码类 com.sun.org.apache.xerces.internal.impl.XMLScanner 行:976 - 981:

else if (c != -1 && XMLChar.isHighSurrogate(c)) {
    if (scanSurrogates(fStringBuffer3)) {
        stringBuffer.append(fStringBuffer3);
    if (entityDepth == fEntityDepth && fNeedNonNormalizedValue){
        fStringBuffer2.append(fStringBuffer3); 
    } 

fStringBuffer3 缓冲区在循环之间不会被清除。

com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl 行中存在类似的代码(相同的方法名称):369 - 375。但是这次缓冲区在循环期间被清除:

else if (c != -1 && XMLChar.isHighSurrogate(c)) {
        fStringBuffer3.clear();
        if (scanSurrogates(fStringBuffer3)) {
            fStringBuffer.append(fStringBuffer3);
        if (entityDepth == fEntityDepth) {
            fStringBuffer2.append(fStringBuffer3);
        }
   }

我检查了java bug数据库,那里没有提到这个bug。 所以我正在寻找解决此问题的方法,用 Woodstox 解析器替换 JAXB 解析器可以解决该错误, 不幸的是,现在对我们来说风险太大了。

我的代码的一般模式是(返回从文件反序列化的对象的方法的一部分):

XMLInputFactory xmlif = XMLInputFactory.newInstance();
XMLStreamReader xmlStreamReader = xmlif.createXMLStreamReader(new FileReader(file)); 
try {
    while(xmlStreamReader.hasNext()){
        boolean skipNext = xmlStreamReader.getEventType() == XMLStreamConstants.START_DOCUMENT;
        xmlStreamReader.next();
        // If its any other element we are unmarshalling it with JAXB
        if((xmlStreamReader.getEventType()== XMLStreamConstants.START_ELEMENT) && !skipNext){
            nextElement = innerDeserializer.deserialize();
        }
    }
}catch (Exception e) {}

有人遇到过这个问题吗?有什么方法可以让我的代码使用第二段代码而不使用 XML 版本 1.1?

最佳答案

如果错误出现在 SAX 解析器中,默认情况下 JAXB 引用实现使用该解析器进行 XML 处理。您可以在输入上创建一个 StAX XMLStreamReader 并让 JAXB 对其进行解码。

关于java - 使用 XMLScanner 反序列化 xml 导致输出字符串更大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24605928/

相关文章:

java - 我可以创建一个已经是另一个类的扩展的类的扩展吗?

xml - 从大型 XML 文件中提取信息

java - 如何使用 JAXB 将 null 值表示为空元素?

eclipse - 从XSD文件生成Java类-JAXB

java - 名字格式

java - 使用 Kotlin 开发 Eclipse 插件

java - 使用 PKIStatus 值验证 RFC 3161 时间戳响应

java - 如何在没有 DOM 的情况下在 java 中读取 XML?

regex - 从纯文本日志文件中提取 xml block

java - 如何根据其运行时类型制作 JAXB Marshaller 编码抽象类?