SAX是基于事件处理xml,需要你继承DefaultHandler类,并且覆盖相应的方法,比如startDocument,endDocument,startElement,endElement,characters等,这里主要说一下characters方法,闲话少说,先说问题。
问题:用characters方法截取标记之间的文本内容,如:<kpiversion>WL_LTE_CORBA_PM_V1.1.0</kpiversion>。但是大数据的xml中,会出现部分字段丢失的问题。90%的截取是没有问题的,另外10%会只截取到部分文本,如只截取到WL_,后面的字串丢失了。
characters定义了三个参数(public void characters(char[] arg0,int arg1,int arg2) throws SAXException),第一个参数是字符数组,第二个是截取的起始位置,第三个是截取的长度。理所当然的认为想要取到中间文本数据,可以如下调用:
public void characters(char[] arg0,int arg2) throws SAXException { this.content =new String(arg0,arg1,arg2); }以为这样就可以得到值,其实这个不正确的,查找资料也证实了,原因是因为两个标记之间的文本大小是不知道的,而char[]是有最大值的,如果超过了2048,他会分几次来调用chatacters方法,第一次取一部分,第二次去后面的,第三次,第四次,直到把文本取完。
但如果本文大小不超过2048,好像有时也会分几次来取,正如我遇到的问题,其实本文并不大,只有十几个字符,但是断点跟踪是发现,第一个只取了前三个字符,所以我用上面定义的characters方法,就只得到了前三个字符。
正确的处理方式应该是:定义一个StringBuffer,在characters方法中重复的拼接,或者利用String直接拼接,直到解析完该标记间的文本。然后在endElement方法中使用解析出的文本,代码如下:
public void characters(char[] arg0,int arg2) throws SAXException { this.content = this.content+new String(arg0,arg2); }
public void endElement(String uri,String localName,String qName) throws SAXException { if(toptag!=null && toptag.equalsIgnoreCase("liststorefield")){ if(oneAlgorithm!=null && currenttag!=null && currenttag.equalsIgnoreCase("carrierid")){ Integer num = Integer.parseInt(content); if(num!=null){ oneAlgorithm.setCarrier_id(num); } } } }
这样字串丢失的问题就解决了。
希望能帮到后来者,呵呵