前段时间写的一个博客是有关于解析xml的,那个上面我用的是dom解析的xml,如果xml不太大的话,那么那样解析没有问题,但是后来我需要解析一个800多k的xml,当运行起项目的时候会出现卡死的状态,项目无法正常跑起来!经过昨天翻阅大量资料,初步认为可以用多线程解决这一问题,后来经测试pass了!还有一种假设就是解析xml的方法有问题,简而言之就是当解析几个数据的时候,可以正常运行,但是大量数据(我那文件是有6000多条数据具体多少个节点没有算)被解析的话就会出现什么内存的问题!最后卡死不动!后来就按着第二个方案查下去终于有了结果,那就是用SAX解析xml,如果处理小数据的话可以用dom,大量数据那么就要用SAX了!下面写一下我用sax解析xml的思路。
public class ReadXmlSAX { /** * @param args * @throws SAXException * @throws ParserConfigurationException */ public static void main(String[] args) throws ParserConfigurationException, SAXException { String a="<?xml version='1.0'?><InvokeReturn xmlns:xsi='" + "http://www.w3.org/2001/XMLSchema-instance' " + "xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" + "<Success>true</Success><Time>2014-03-10T18:10:24.9960547+08:00" + "</Time></InvokeReturn>";//需要解析的xml数据(注意一定要格式正确) try { SAXParserFactory factory = SAXParserFactory.newInstance();//得到sax解析工厂 SAXParser saxParser = factory.newSAXParser();//创建解析器 DefaultHandler handler = new DefaultHandler() { //声明判断这几个字段是否存在 boolean bsuccess=false; boolean btime=false; boolean bindex = false; boolean bkey = false; boolean bvalue = false; public void startElement(String uri, String localName, String qName, Attributes attributes) //判断是否与标签名字一致 throws SAXException { System.out.println("Start Element :" + qName); if(qName.equalsIgnoreCase("Success")){ bsuccess=true; } if(qName.equalsIgnoreCase("Time")){ btime=true; } if (qName.equalsIgnoreCase("Index")) { bindex = true; } if (qName.equalsIgnoreCase("Key")) { bkey = true; } if (qName.equalsIgnoreCase("Value")) { bvalue = true; } for (int i = 0; i < attributes.getLength(); i++) { System.out.println("attribute name:" + attributes.getQName(i)); System.out.println("attribute value:" + attributes.getValue(i)); } } /** * 解析XML时,当读到结束一个元素标签时 * */ public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("End Element :" + qName); } //判断标签是否存在 public void characters(char ch[], int start, int length) throws SAXException { if(bsuccess){ System.out.println("success :"+new String(ch,start,length)); bsuccess=false; } if(btime){ System.out.println("time: "+new String(ch,start,length)); btime=false; } if (bindex) { System.out.println("index : " + new String(ch, start, length)); bindex = false; } if (bkey) { System.out.println("key : " + new String(ch, start, length)); bkey = false; } if (bvalue) { System.out.println("value : " + new String(ch, start, length)); bvalue = false; } } }; //根据字符串读取 InputStream is = new ByteArrayInputStream(a.getBytes("ISO-8859-1"));//将String字符串转换为InputStream saxParser.parse(is, handler); //saxParser.parse("d:\\sss.xml",handler);//从本地读取 } catch (Exception e) { e.printStackTrace(); } } }
需要导入的包就是dom4j.jar
特别鸣谢:
51CTO论坛-JAVA交流
170297048
一大堆人
将String转换为InputStream的这篇文章:http://zhoujingxian.iteye.com/blog/1682480
以及诸多关于sax的例子的博客!!