没有缓存的Axiom getTextAsStream Parser已经到达了文档的末尾。没有找到兄弟姐妹

时间:2013-01-11 06:24:37

标签: java axis2 axiom

我在Axis2中使用Axiom从SOAP消息的大型base64Binary部分提取文本。我的接收器没有使用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>

在读取base64Binary数据后,我在childrenIterator.hasNext()行上收到此异常:

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()处于错误状态。

之前有没有人见过这个错误?我使用Axiom的方式有问题吗?

1 个答案:

答案 0 :(得分:0)

我最终根本没有使用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;
    }
}