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

1

Наш процесс обновления продукта включает в себя экспорт старой схемы DB в файлы (сериализация 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?

Теги:
jaxb
stax
woodstox

1 ответ

0

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

  • 0
    Это то, что мы делаем, читая большие блоки документов с помощью StAX, а каждое событие START_ELEMENT анализируется с помощью JAXB.
  • 0
    @MaximKirilov - я запутался, когда тогда появляется SAX-парсер.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню