Java 使用XMLScanner反序列化xml导致输出字符串变大

Java 使用XMLScanner反序列化xml导致输出字符串变大,java,xml,jaxb,stax,woodstox,Java,Xml,Jaxb,Stax,Woodstox,我们的产品升级过程包括旧模式数据库导出到文件(JAXB序列化),然后导入到新模式(StAX+JAXB)。有时,由于插入错误导致升级失败,这些错误是由于值超过了它们以前从同一DB表导出的最大大小dispite而导致的。 当反序列化xml(在本例中为Jaxb,但它不只是与Jaxb相关)并且其中一个属性的值具有高代理UTF-8字符序列时,会发生这种情况SAX解析器存在错误,导致输出字符串变大: 3个字符->(1+2+3=)6个字符。 6个字符->(1+2+3+4+5+6=)21个字符。 (源字符

我们的产品升级过程包括旧模式数据库导出到文件(JAXB序列化),然后导入到新模式(StAX+JAXB)。有时,由于插入错误导致升级失败,这些错误是由于值超过了它们以前从同一DB表导出的最大大小dispite而导致的。

当反序列化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。但这一次在循环过程中缓冲区被清除:

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

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

sombody遇到过这个问题吗?有没有办法让我的代码使用第二段代码而不使用XML 1.1版?

如果错误在SAX解析器中,默认情况下JAXB参考实现用于XML处理。您可以在输入上创建一个StAX
XMLStreamReader
,并让JAXB解组它。

这就是我们正在做的,使用StAX读取大文档块,同时使用JAXB解析每个START\u元素事件。@MaximKirilov-我不知道SAX解析器是从哪里来的。谢谢您的帮助,我编辑了上面的代码并添加了我的代码的一般模式,它显示了StAX与JAXB.@ MulkKiILIOVO的组合——所以StAX方法可以让你认为它是有风险的,为什么你认为它有风险?除了Woodstox,JDK/JRE中还有一个StAX解析器,这对您有用吗?
else if (c != -1 && XMLChar.isHighSurrogate(c)) {
        fStringBuffer3.clear();
        if (scanSurrogates(fStringBuffer3)) {
            fStringBuffer.append(fStringBuffer3);
        if (entityDepth == fEntityDepth) {
            fStringBuffer2.append(fStringBuffer3);
        }
   }
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) {}