SAX解析XML

SAX解析是一种与PULL解析器类似的XML解析的方法,不同的是,使用PULL解析需要程序员自己获取产生的事件做相应的操作。SAX解析的特点是逐行扫描文档,一边扫描一边解析,这种方式比起一次性将整个XML文件加载到内存中的DOM解析方式也更为安全(不易造成内存溢出),也更为快速有效。同时,SAX还可以在解析文档的任意时刻停止解析。当然,它也有缺点,那就是相对来说,SAX的操作复杂一点。

 

SAX事件驱动型XML解析的一个标准接口不会改变 SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

 

大多数SAX都会产生以下类型的事件:

1.在文档的开始和结束时触发文档处理事件。

2.在文档内每一XML元素接受解析的前后触发元素事件。

3.任何元数据通常由单独的事件处理

4.在处理文档的DTDSchema时产生DTDSchema事件。

5.产生错误事件用来通知主机应用程序解析错误。

 

SAX解析的步骤

1,确定xml文件位置

File f  = new File(xml文件位置”);

2,获取SAXParserFactory 对象

SAXParserFactory  fac = SAXParserFactory.newInstance();

3,获取SAXParser解析器对象

SAXParser parser = fac.newSAXParser();

4,开始解析XML

parse(File f, DefaultHandler dh)

f: xml文件

dh: sax解析处理器,SAX解析所有触发的方法都在处理器里面处理


SAX解析XML案例:读取contacts.xml所有的联系人,并封装到集合中

contacts.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<contacts>
	<linkman id="1">
		<name>乔峰</name>
		<email>qf@126.com</email>
		<address>襄阳</address>
		<group>丐帮</group>
	</linkman>
	<linkman id="2">
		<name>段誉</name>
		<email>duanyu@126.com</email>
		<address>云南</address>
		<group>大理</group>
	</linkman>
	<linkman id="3">
		<name>虚竹</name>
		<email>xuzhu@126.com</email>
		<address>少林寺</address>
		<group>广东</group>
	</linkman>
</contacts>

SAX解析过程:

//取出所有xml文件中所有联系人并封装到list集合中
public class SAXParserTest {
	
	@Test//获取SAXParser对象
	public void testSAXParser() throws Exception{
		File f = new File("E:/MyEclipse/workspace/day02-junit-xml/contacts.xml");
		//1、创建SAXParserFactory对象
		SAXParserFactory fac = SAXParserFactory.newInstance();
		//2.获取SAXParser对象
		SAXParser sax = fac.newSAXParser();
		//3.解析xml文件
		ContactDafultHandler dh = new ContactDafultHandler();
		sax.parse(f, dh);
		
		List<Contact> handler = dh.getList();
		for (Contact contact : handler) {
			System.out.println(contact);
		}
		
	}

}


SAX解析处理器:
ContactDafultHandler.java

public class ContactDafultHandler extends DefaultHandler{
	//list集合
	private List<Contact> list = null;
	//联系人对象
	Contact con ;
	//上一个标签的名称
	String preTag;
	
	public List<Contact> getList(){
		return list;
	}
	

	//文档开始时调用
	public void startDocument() throws SAXException {
		list = new ArrayList<>();//文档开始时创建集合对象
	}

	//文档结束时调用
	public void endDocument() throws SAXException {
		
	}

	//元素开始时调用
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if("linkman".equals(qName)){
			con = new Contact();
			String id = attributes.getValue("id");//得到id
			//con.setId(Long.valueOf(id));
			con.setId(id);
			
		}
		preTag = qName;
	}

	//元素结束时调用
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		preTag = null;
	}

	//读取文本内容时调用
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String value = new String(ch,start,length);
		if(preTag != null){
			if("name".equals(preTag)){
				con.setName(value);
			}
			if("email".equals(preTag)){
				con.setEmail(value);
			}
			if("address".equals(preTag)){
				con.setAddress(value);
			}
			if("group".equals(preTag)){
				con.setGroup(value);
			}
			list.add(con);
		}
	}
	

}

封装数据:

Contact.java

public class Contact {
	private String id;
	private String name;
	private String email;
	private String address;
	private String group;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getGroup() {
		return group;
	}
	public void setGroup(String group) {
		this.group = group;
	}
	
	public String toString(){
		return id +"," + name + "," + email +"," + address +"," +group;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值