繁体   English   中英

XMLStreamReader无法读取完整标签

[英]XMLStreamReader doesn't read complete tag

我正在使用XMLStreamReader解析XML。 <dbresponse>标记中,有一些从数据库( WebRowSet对象)加载的数据。 问题在于此标记的内容非常长(例如,数百千字节-数据在Base64中编码),但是input.getText()仅从其中读取16.394个字符。

我100%确信进入XMLStreamReader数据是可以的。

我在这里找到了其他答案,但它不能解决我的问题,我当然可以使用其他方式读取数据,但是我想知道这个问题是什么。

有人知道如何获取全部内容吗?

我的代码:

            input = xmlFactory.createXMLStreamReader(new ByteArrayInputStream(xmlData.getBytes("UTF-8")));

        while(input.hasNext()){
            if(input.getEventType() == XMLStreamConstants.START_ELEMENT){
                element = input.getName().getLocalPart();

                switch(element.toLowerCase()){
                    case "transactionresponse":
                        int transactionStatus = 0;

                        transactionResponse = new TransactionResponse(); 
                        for(int i=0; i<input.getAttributeCount(); i++){
                            switch(input.getAttributeLocalName(i)){
                                case "status": transactionStatus = TransactionResponse.getStatusFromName(input.getAttributeValue(i));
                            }
                        }

                        transactionResponse.setStatus(transactionStatus);

                        break;
                    case "dbresponse":
                        for(int i=0; i<input.getAttributeCount(); i++){
                            switch(input.getAttributeLocalName(i)){
                                case "request_id": id = Integer.parseInt(input.getAttributeValue(i)); break;
                                case "status": status = Response.getStatusFromName(input.getAttributeValue(i));
                            }
                        }

                        break;
                }
            }else if(input.getEventType() == XMLStreamConstants.CHARACTERS){
                switch(element.toLowerCase()){
                    case "dbresponse": 
                        String data = input.getText();

                        if(!data.equals("\n")){
                            data = new String(Base64.decode(data), "UTF-8");
                        }

                        Response response = new Response(data, status, id);

                        if(transactionResponse != null){
                            transactionResponse.addResponse(response);
                        }else{
                            this.addResponse(response);
                        }

                        id = -1;
                        status = -1;

                        break;
                }

                element = "";
            }else if(input.getEventType() == XMLStreamConstants.END_ELEMENT){
                switch(input.getLocalName().toLowerCase()){
                    case "transactionresponse": this.addTransactionResponse(transactionResponse); transactionResponse = null; break;
                }
            }

            input.next();

事件驱动的XML解析器(例如XMLStreamReader旨在允许您解析XML,而不必一次将其全部读入内存,如果您拥有非常大的XML,这是非常必要的。

这种设计可以读取特定的数据缓冲区,并在遇到“有趣的”东西时为您提供事件,例如标签的开头,标签的结尾等。

但是它读取的缓冲区不是无限的,因为它意在处理大型XML文件,就像您拥有的一样。 因此,标签中的大文本可能由几个连续的CHARACTERS事件表示

也就是说,当您获得CHARACTERS事件时,不能保证它包含整个文本。 如果文本对于读者的缓冲区而言太长,您将仅获得随后的更多CHARACTERS事件。

由于您仅从第一个CHARACTERS事件读取数据,因此它不是全部数据。

处理此类文件的正确方法是:

  • 当您对感兴趣的元素获取START_ELEMENT事件时,就为存储文本做好了准备。 例如,创建一个StringBuilder ,或打开一个文件进行写入等。
  • 对于随后的每个CHARACTERS事件,您都将文本追加到存储中( StringBuilder ,即文件)。
  • 获得相同元素的END_ELEMENT事件后,您就完成了对数据的累加,并做了任何需要做的事情。

实际上,这就是getElementText()方法为您所做的-在进行CHARACTERS事件时将数据存储在StringBuffer ,直到达到END_ELEMENT为止。

底线:您只有在碰到END_ELEMENT事件时才知道全部数据。 不能保证文本将在单个CHARACTERS事件中。

我认为XMLStreamReader将数据分块,所以也许尝试循环getText()来连接所有分块?

那么getElementText()方法呢?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM