SAX方式解析XML

  sax解析分为以下几步:

1 获取一个saxparserfactory

2 获取一个解析器

3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类,这个实现类里写具体的解析逻辑

4 开始解析xml。

结构层次图:

具体如下面的代码:

mySAXparser:

package com.imooc.test;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class mySAXparser {
	public static void main(String[] args) {
		//1 获取一个saxparserfactory
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			//2 获取一个解析器
			SAXParser parser = factory.newSAXParser();
			/*
			 * 3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类
			 * 这个实现类里写具体的解析逻辑
			 */
			myHandler handler = new myHandler();
			//4 开始解析xml,
			parser.parse("books.xml",handler);
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  myHandler:

package sax;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class myHandler extends DefaultHandler {
	int i =0;
	int j = 0;
	String value = null;
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
		System.out.println("startDocument开始解析..............");
		
	}
	
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
		System.out.println("endDocument结束解析............");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		super.startElement(uri, localName, qName, attributes);
		/*
		 * qName:The qualified name (with prefix),
		 *  or the empty string if qualified names are not available.
		 *  qName:实际上就是标签名的名字,如<sex>1</sex> 那么qName就代指的这个标签名,sex
		 *  
		 */
		if(qName.equals("book")){
			i++;
			String value = attributes.getValue("size");
			int len = attributes.getLength();
			System.out.println("len:"+len);
			for(int k=0;k<len;k++){
				int m = k+1;
				System.out.println("属性"+m+":"+attributes.getQName(k));
			}
			System.out.println("book.size:"+value);
			System.out.println("第"+i+"处,解析到book元素的标签。。。");
		}
		if(qName.equals("bookstore")){
			j++;
			System.out.println("第"+j+"处,解析到bookstore元素的标签。。。");
		}
		
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		System.out.println("第"+i+",endElement结束");
		
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		//new String(ch, start, length)用来生成一个元素中标签之间的具体的文本
		value = new String(ch, start, length);//加入正好解析到<name>冰与火之歌</name>时,那么value="冰与火之歌"
		System.out.println("================节点值是:" + value);
		if (!value.trim().equals("")) {
			
			System.out.println(i+"节点值是:" + value);
		}
	}
}

  

  books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="1">
		<name>冰与火之歌</name>
		<author>乔治马丁</author>
		<year>2014</year>
		<price>89</price>
	</book>
	<book id="2">
		<name>安徒生童话</name>
		<year>2004</year>
		<price>77</price>
		<language>English</language>
	</book>	
</bookstore>

  解析结果下:

startDocument开始解析..............
第1处,解析到bookstore元素的标签。。。
================节点值是:

len:2
属性1:id
属性2:size
book.size:23
第1处,解析到book元素的标签。。。
================节点值是:

================节点值是:冰与火之歌
1节点值是:冰与火之歌
第1,endElement结束
================节点值是:

================节点值是:乔治马丁
1节点值是:乔治马丁
第1,endElement结束
================节点值是:

================节点值是:2014
1节点值是:2014
第1,endElement结束
================节点值是:

================节点值是:89
1节点值是:89
第1,endElement结束
================节点值是:

第1,endElement结束
================节点值是:

len:1
属性1:id
book.size:null
第2处,解析到book元素的标签。。。
================节点值是:

================节点值是:安徒生童话
2节点值是:安徒生童话
第2,endElement结束
================节点值是:

================节点值是:2004
2节点值是:2004
第2,endElement结束
================节点值是:

================节点值是:77
2节点值是:77
第2,endElement结束
================节点值是:

================节点值是:English
2节点值是:English
第2,endElement结束
================节点值是:

第2,endElement结束
================节点值是:

第2,endElement结束
endDocument结束解析............

 

 

 

 

 

 sax解析的myHandler这个类继承了DefaultHandler,具体的解析逻辑就是写在这个myHandler

中,覆盖的方法的执行顺序是:

1. startDocument()

2. 

startElement(String uri, String localName, String qName,
Attributes attributes)

3. endElement(String uri, String localName, String qName)

4. characters(char[] ch, int start, int length)

...

n. endDocument()

其中的...省略号部分一直重复的执行2,3,4两个步骤,主要是根据xml的具体情形,遇到一个具体元素就会执行2,3,4三个步骤一次。如上面的

xml中的

<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>89</price>

,这样就会重复执行2,3,4步骤四次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值