我正在使用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();
答案 0 :(得分:1)
事件驱动的XML解析器(如XMLStreamReader
)旨在允许您解析XML而无需一次性将其读入内存,这在您拥有非常大的XML时非常重要。< / p>
设计是这样的,它可以读取某个数据缓冲区,并为您提供事件,因为它会遇到“有趣”的内容,例如标记的开头,标记的结尾等等。
但它读取的缓冲区并不是无限的,因为它意味着处理大型XML文件,就像你拥有的那样。因此,标记中的大型文字可以由连续几次CHARACTERS
个事件表示。
也就是说,当您收到CHARACTERS
事件时,无法保证它包含整个文本。如果文本对于读者的缓冲区而言太长,您只会获得更多CHARACTERS
个事件。
由于您只是从第一个CHARACTERS
事件中读取数据,因此不是整个数据。
使用此类文件的正确方法是:
START_ELEMENT
事件时,您将为存储文本做好准备。例如,创建一个StringBuilder
,或打开一个文件进行写作等。CHARACTERS
事件,您都会将文本附加到存储空间(StringBuilder
,即文件)。END_ELEMENT
事件后,您将完成数据的累积,并执行您需要执行的任何操作。事实上,这就是getElementText()
method为您所做的事情 - 在StringBuffer
事件中累积数据,直到它遇到CHARACTERS
。
结论:您只知道在点击END_ELEMENT
事件时获得了整个数据。无法保证文本将在单个END_ELEMENT
事件中。
答案 1 :(得分:0)
我认为XMLStreamReader会对数据进行分块,所以也许尝试循环getText()来连接所有块?
getElementText()方法怎么样?