Java与XML原来可以这么简单--基于SAX标准

DOM处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的:这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存。更甚的是,Java VM中最耗资源的一个动作就是new一个对象,要存储DOM中的节点相对应得也就要new很多个对象,对性能的影响显而易见了。

 

在SAX解析器装载XML文件时,它遍历文件文档并在其主机应用程序中产生事件(经由回调函数指派函数 或者任何可调用平台完成这一功能)表示这一过程。在文档的开始和结束时触发文档处理事件。在文档内每一XML元素接受解析的前后触发元素 事件。任何元数据通常都由单独的事件交付。在处理文档的DTD或Schema时产生DTD 或Schema事件。错误事件用来通知主机应用程序解析错误。

 

 

SAX对DOM,在什么情况下采用这种或者那种API 并没有确定的严格规则;具体情况具体分析。所有的SAX处理都在一次遍历中完成的;因此,在解析同等大小的文档时SAX通常会相比DOM提供更好的性能 (因为DOM必须遍历树 结构)。此外,与DOM是比,因为在给定的时间之内只需要XML文档的一部分装入内存,所以SAX通常在处理更大文件时内存的利用效率也来得更高(DOM在开始解析文档之前必须把全部XML文档装入内存)。

SAX也不是没有缺点。SAX应用程序一般都比较长,程序中充斥着大量的if/else结构用来确定处理特定元素 时所采用的运动。同样的,处理多个XML元素之间散布的数据结构也很成问题,因为解析事件之间必须保存中间数据。最后,SAX应用程序的事件 处理结构一般意味着SAX应用程序是针对特定文件结构定制构建的,而DOM应用程序则更具一般性。

 

下面献上自己写的一个例子,写的不好望多多包含:

 

public class SAXCounter2 extends DefaultHandler {

	public static void main(String[] args) {
		String fileName = "main.xml";
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser saxParser = null;

		try {
			saxParser = spf.newSAXParser();// 创建出SAX解析
			// 将解析器和解析对象XMLDOMData.xml联系起来,同时指定事件回调方法的对象开始解析
			saxParser.parse(new File(fileName), new SAXCounter2());
		}  catch (SAXException se) {
			System.err.println(se.getMessage());
			System.exit(1);
		} catch (IOException ioe) {
			System.err.println(ioe);
			System.exit(1);
		} catch (Exception ex) {
			System.err.println(ex);
			System.exit(1);
		} 
	}
	// 定义开始解析xml的方法
	public void startDocument() throws SAXException {
		System.out.println("SAX Event: START DOCUMENT(文档开始)");
	}

	public void endDocument() throws SAXException {
		System.out.println("SAX Event: END DOCUMENT(文档结束)");
	}

	// 对每一个<xxx>开始元属性进行处理
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		// 打印除该标签的名称
		System.out.println("SAX Event: START ELEMENT[ " + qName + " ]");
		for (int i = 0; i < atts.getLength(); i++) // 如果 有属 性,我 们 也一并打 印 出来...
		{
			/*
			 * 对带有属性的标签如何获得其属性值,比较困难。需要编程startElement方法中的Attributes参数
			 */
			System.out.print("ATTRIBUTE: " + atts.getLocalName(i) + "--VALUE: "
					+ atts.getValue(i) + "\n");
		}
	}
	// 在遇到</xxx>结束后
	public void endElement(String namespaceURI, String localName, String qName)
			throws SAXException {
		System.out.println("SAX Event: END ELEMENT[ " + qName + " ]\n");
	}
	// 这里将是处理<xxx></xxx>之间的标签体的值的方法
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		System.out.print("\nSAX Event: CHARACTERS start:");
		try {
			OutputStreamWriter outw = new OutputStreamWriter(System.out);
			outw.write(ch, start, length); // 将该标签体的文字串输出到控制台上
			outw.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.print("\nSAX Event: CHARACTERS end\n");
	}

}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值