Аксиома getTextAsStream без кэширования Parser уже достиг конца документа. Братьев и сестер не найдено

Я использую Axiom в Axis2 для извлечения текста из большого раздела base64Binary сообщения SOAP. Мой приемник не использует MTOM и использует OMElement.getTextAsStream( false ) извлечь текст. Код выглядит примерно так:

final Iterator<OMElement> childrenIterator = uploadFile.getChildElements();
while ( childrenIterator.hasNext() )
{
    final OMElement element = childrenIterator.next();
    if ( "fileID".equals( element.getLocalName() ) )
    {
        fileID = element.getText();
    }
    // fileContent contains a large base64Binary block
    else if ( "fileContent".equals( element.getLocalName() ) )
    {
        Reader reader = element.getTextAsStream( false );

        final char[] buf = new char[BUFFER_SIZE];
        int len = 0;
        while ( (len = reader.read( buf ) ) >= 0 )
        {
            if ( len > 0 )
            {
                // Process chunk here
            }
        }
    }
}

Пример XML будет выглядеть

<uploadFile>
    <fileID>id</fileID>
    <fileContent>~500kB of base64 data</fileContent>
</uploadFile>

Я получаю это исключение на childrenIterator.hasNext() строка после считывания base64Binary данных:

Caused by: org.apache.axiom.om.OMException: Parser has already reached end of the document. No siblings found
    at org.apache.axiom.om.impl.llom.OMElementImpl.getNextOMSibling(OMElementImpl.java:359)
    at org.apache.axiom.om.impl.traverse.OMChildrenIterator.getNextNode(OMChildrenIterator.java:36)
    at org.apache.axiom.om.impl.traverse.OMAbstractIterator.hasNext(OMAbstractIterator.java:69)
    at org.apache.axiom.om.impl.traverse.OMFilterIterator.hasNext(OMFilterIterator.java:54)

Я провел некоторое исследование, и это определенно связано с тем, что я устанавливаю кеш в false при звонке getTextAsStream(), Мне нужно сделать это, потому что потенциальный размер данных base64 может составлять сотни мегабайт.

Кажется, проблема в том, что TextFromElementReader продвигает основную XMLStreamReader на событие END_ELEMENT. OMElementImpl.getNextOMSibling() затем звонит next() на основе XMLStreamReader и получает событие END_DOCUMENT. Кажется, что TextFromElementReader должен встретиться с END_ELEMENT, чтобы знать, что он достиг конца текстового сегмента, но это оставляет основной XMLStreamReader в неправильном состоянии для OMElementImpl.getNextOMSibling(),

Кто-нибудь видел эту ошибку раньше? Что-то не так с тем, как я использую Аксиому?

1 ответ

Решение

Я закончил тем, что вообще не использовал getTextAsReader. Вместо этого я перебрал дочерние текстовые узлы и таким образом обработал текстовое содержимое кусками. Синтаксический анализатор настроен так, что он не объединяется, поэтому я получаю текстовые узлы разумного размера, а не один большой.

OMNode child = omElement.getFirstOMChild();
while ( child != null )
{
    if ( child instanceof OMText )
    {
        // process 'child' text here

        final OMNode nextSibling = child.getNextOMSibling();
        child.detach();    // detach from OM to keep memory usage low
        child = nextSibling;
    }
}
Другие вопросы по тегам