前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java解析xml技术(一)

java解析xml技术(一)

作者头像
forrestlin
发布2018-05-23 17:31:51
6830
发布2018-05-23 17:31:51
举报
文章被收录于专栏:蜉蝣禅修之道蜉蝣禅修之道

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

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

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

1.

代码语言:javascript
复制
 //构建saxfactory和saxparser,利用factory可以把验证与解析xml分离,更好地实现低耦合
		 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		 SAXParser noteParser = saxParserFactory.newSAXParser();

2.调用saxparser对象的parse()方法解析xml文档,调用该方法时需要传入一个defaulthandler对象,defaulthandler这个类实现了contenthandler、dtdhandler、entityresolver和errorhandler4个接口,sax用该类进行了简化事件适配器和事件监听器的关系。

代码语言:javascript
复制
//构建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里所有节点的数据都是文本数据,

代码语言:javascript
复制
/**
	 * 解析xml元素的文本数据
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
	}

(2)startElement应该把它放在前面的,但是通常用它来获取节点的属性

代码语言:javascript
复制
/**
	 * 开始解析xml元素属性
	 * 
	 * @param qName
	 *            元素名字通常与localName相同
	 * @param attributes
	 *            元素的属性数组
	 */
	@Override
	public 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节点触发

代码语言:javascript
复制
@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
	}

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

dom

sax

速度

需要一次性装入整份xml文档,并将xml文档转换为dom树,因此速度较慢

顺序解析xml文档,无须一次装入xml文档,因此速度很快

重复访问

将xml文档转换为dom树以后,整个解析阶段dom树常驻内存,适合重复访问,效率很好

顺序解析xml文档,不保存已访问的数据,因此不适合重复访问

内存要求

内存占用率大

不保存已访问数据,内存占用少

修改

可以读取也可以修改节点内容

只能读取

优缺点

可以根据dom树重复访问,但速度慢,内存占用大

不能重复访问,但速度快,内存占用小

最后,我说一下,重复访问到底有什么用?举个反例吧,sax不支持重复访问,也就是说它只顾当前节点,无法得到上下文信息,不知道当前节点的父节点和子节点的任何信息,例如下面的xml代码,你只可能知道这是一本叫疯狂java讲义的书,还有price是50,但是你不知道疯狂java讲义是50块

代码语言:javascript
复制
<book name="疯狂java讲义">
<price>50</price>
</book>

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012年07月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档