java解析xml技术(一)

来源:互联网 发布:ios开发播放网络视频 编辑:程序博客网 时间:2024/04/29 16:01

最近在做xml的解析工作,过去一直没有认真学习过xml,但是xml确实是一种很方便优秀的数据保存格式,对数据的描述非常清晰,我们是时候了解它的奥秘了。

xml是一种数据的保存格式,只关注数据的内容,不管数据的表现形式。它的跨平台性使很多软件都选择其为配置或软件数据的保存格式,而java这个跨平台的编程语言也对xml解析进行封装。

首先,jdk里面封装的xml解析方式包括dom和sax,对于dom方式,在html里面我们就已经了解得很多了,这里我不多说。而sax应该是我刚刚接触的xml特有的解析方式,他就像一个探地雷的工兵,在xml文档中探索,没经过一个元素开始、元素结束、处理指令开始、处理指令结束……都会向外报告,触发回调函数,废话不多说,直接上java代码:

1.

 //构建saxfactory和saxparser,利用factory可以把验证与解析xml分离,更好地实现低耦合 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser noteParser = saxParserFactory.newSAXParser();
2.调用saxparser对象的parse()方法解析xml文档,调用该方法时需要传入一个defaulthandler对象,defaulthandler这个类实现了contenthandler、dtdhandler、entityresolver和errorhandler4个接口,sax用该类进行了简化事件适配器和事件监听器的关系。

//构建defaultHandler监听xml事件,svghandler继承了defaulthandler SVGhandler notehandler=new SVGhandler(); //开始解析xml noteParser.parse(fis, notehandler);
3.然后再svghandler里面进行xml的解析,它重写了defaulthandler几个重要的方法。

(1)characters()中可以通过new String(ch,start,length)得到当前节点的文本数据,xml里所有节点的数据都是文本数据,

/** * 解析xml元素的文本数据 */@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {// TODO Auto-generated method stubsuper.characters(ch, start, length);}
(2)startElement应该把它放在前面的,但是通常用它来获取节点的属性
/** * 开始解析xml元素属性 *  * @param qName *            元素名字通常与localName相同 * @param attributes *            元素的属性数组 */@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// 该结点属性的个数int len = attributes.getLength();currentTag = qName;if(currentTag.equals("mark")){note=new LineNotes();}if (len > 0) {// System.out.println("<" + currentTag + ">Ԫ�ص���������:" );for (int i = 0; i < len; i++) {if (attributes.getQName(i).equals("d"))// System.out.println(attributes.getQName(i) + "--->"// + attributes.getValue(i));{String path = attributes.getValue(i);// stringTokenizer����һ�ʵıʼ�StringTokenizer stringTokenizer = new StringTokenizer(path);}}}}
(3)endElement结束解析xml节点触发
@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// TODO Auto-generated method stubsuper.endElement(uri, localName, qName);}

好吧,代码就说到这里,下面对dom和sax这两种方式比较一下:

 domsax速度需要一次性装入整份xml文档,并将xml文档转换为dom树,因此速度较慢顺序解析xml文档,无须一次装入xml文档,因此速度很快重复访问将xml文档转换为dom树以后,整个解析阶段dom树常驻内存,适合重复访问,效率很好顺序解析xml文档,不保存已访问的数据,因此不适合重复访问内存要求内存占用率大不保存已访问数据,内存占用少修改可以读取也可以修改节点内容只能读取优缺点可以根据dom树重复访问,但速度慢,内存占用大不能重复访问,但速度快,内存占用小
最后,我说一下,重复访问到底有什么用?举个反例吧,sax不支持重复访问,也就是说它只顾当前节点,无法得到上下文信息,不知道当前节点的父节点和子节点的任何信息,例如下面的xml代码,你只可能知道这是一本叫疯狂java讲义的书,还有price是50,但是你不知道疯狂java讲义是50块

<book name="疯狂java讲义"><price>50</price></book>

一般的xml都是上下文相关的,所以尽管sax很快,但这个缺点对于它来说是一个很大的限制。



原创粉丝点击