Аксиома 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;
}
}