Десериализация XML с XMLScanner, что приводит к увеличению выходной строки

Процесс обновления нашего продукта включает в себя экспорт старой схемы БД в файлы (сериализация 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, эта ошибка там не упоминается. Поэтому я ищу решение этой проблемы, замена парсера JAXB на парсер Woodstox решает проблему, к сожалению, для нас это слишком рискованно.

Общий шаблон моего кода (часть метода, который возвращает объект, который был десериализован из файла):

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?

1 ответ

Если ошибка в синтаксическом анализаторе SAX, который по умолчанию эталонная реализация JAXB использует для обработки XML. Вы могли бы создать StAX XMLStreamReader на входе и JAXB разобрать это.

Другие вопросы по тегам