Javaweb学习笔记之XML(六):SAX读取XML文档

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29331365/article/details/89923251
package com.demo.b_sax;

import java.io.File;

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

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

/*
 * XML 解析的两种方式:Dom4J解析 和 SAX解析
 * 
 * DOM4J 解析原理:一次性把文档加载进内存,然后在内存中构建 Document 树。
 * 	缺点:读取大容量的 xml 文档时,占用的内存过大。
 * 
 * SAX 解析原理:加载一点,读取一点,解析一点。对内存要求比较低。
 * 	SAX 解析内置在 jdk 中,可以直接使用;
 * 	
 * 	DOM 解析和 SAX 解析比较:
 * 		DOM 解析:
 * 			1、原理:XML 解析器一次性把整个 XML 文档加载进内存,然后在内存中构建一棵 Document 的对象树,
 * 				通过 Document 对象,得到树上的节点对象,通过节点对象操作 XML 文档的内容。
 * 				一次性加载 XML 文档,不适合大容量的文件读取,比较占用内存;
 * 			2、DOM 解析可以任意进行增删改查;
 * 			3、DOM 解析可以读取任意位置的数据,甚至往回读;
 * 			4、DOM 解析是面向对象的编程方法(Node、Element、Attribute),开发编码比较简单;
 * 		SAX 解析:
 * 			1、原理:加载一点,读取一点,解析一点。适合大容量文件的读取。
 * 			2、SAX 解析只能读取;
 * 			3、SAX 解析只能从上往下,按顺序读取,不能往回读;
 * 			4、SAX 解析是基于事件的读取方法,开发编码相对复杂。
 * 	
 * 核心 API:
 * 	SAXParser 类:解析器,用于读取和解析 XML 文档;
 * 	parse(File f, DefaultHandler dh) 方法:解析 XML 文件;
 * 		参数1:File,表示要解析的 xml 文件;
 * 		参数2:DefaultHandler,SAX 事件处理程序。使用 DefaultHandler 的子类。
 */

public class Demo1 {

	@Test
	public void test1() throws Exception {
		// 1、创建 SAXParser 解析器对象
		SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

		// 2、调用 parse 方法;读取 xml 文档时,会自动执行 MyDefaultHandler 类。
		parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
	}

	/**
	 * SAX 处理程序 从上往下,逐部分读取;
	 */
	class MyDefaultHandler extends DefaultHandler {

		/**
		 * 读到文档开始时调用
		 */
		@Override
		public void startDocument() throws SAXException {
			System.out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
		}

		/**
		 * 读到文档结束时调用
		 */
		@Override
		public void endDocument() throws SAXException {
			// System.out.println("endDocument");
		}

		/**
		 * 读到开始标签时调用;属性在开始标签中。前面两个参数不用;
		 * 
		 * @param qName
		 *            表示开始标签的标签名
		 * @param attributes
		 *            表示开始标签内包含的属性
		 */
		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes)
				throws SAXException {
			System.out.print("<" + qName);

			// 获取属性
			for (int i = 0; i < attributes.getLength(); i++) {
				String attrName = attributes.getQName(i); // 获取属性的名称
				String attrValue = attributes.getValue(i); // 获取属性的值
				System.out.print(" " + attrName + "=\"" + attrValue + "\"");
				;
			}

			System.out.print(">");
		}

		/**
		 * 读到 结束标签 时调用
		 * 
		 * @param qName
		 *            表示结束标签的名字
		 */
		@Override
		public void endElement(String uri, String localName, String qName) throws SAXException {
			System.out.print("</" + qName + ">");
		}

		/**
		 * 读到 文本内容 时调用
		 * 
		 * @param ch
		 *            表示读取到的 XML 文档中所有的文本内容
		 * @param start
		 *            表示当前文本内容的开始位置
		 * @param length
		 *            表示当前文本内容的长度
		 */
		@Override
		public void characters(char[] ch, int start, int length) throws SAXException {
			System.out.print(new String(ch, start, length));
		}

	}

}
package com.demo.b_sax;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

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

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

import com.demo.a_dom4j.Contact;

/*
 * 使用 SAX 方法读取 XML 文档,将数据封装到 Javabean 中
 */

public class Demo2 {

	@Test
	public void test1() throws Exception{
		
		// 创建 SAXParser 解析器对象
		SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
		
		// 调用 parse() 方法
		parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
	}
	
	class MyDefaultHandler extends DefaultHandler{
		
		/*
		 * 思路:
		 * 	1、每次读取到 contact 开始标签时,创建一个 contact 对象;
		 * 	2、把每个 contact 标签的内容存储到 contact 对象中;
		 * 	3、每次读到 contact 结束标签时,把 contact 对象放入 list 集合中;
		 */
		
		List<Contact> lists = null;	// 存储 javabean 对象的集合
		Contact contact = null;		// javabean 对象
		String currTag = "";		// 记录当前标签
		
		/**
		 * 读到 文档开始 时调用
		 */
		@Override
		public void startDocument() throws SAXException {
			lists = new ArrayList<Contact>();
		}
		
		/**
		 * 读到 文档结束 时调用
		 */
		@Override
		public void endDocument() throws SAXException {
			for (Contact cont : lists){
				System.out.println(cont);
			}
		}
		
		/**
		 * 读到 开始标签 时调用
		 */
		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes)
				throws SAXException {

			// 记录当前 标签的名字
			currTag = qName;
			
			// 每次读到 contact 开始标签时创建一个 contact 对象
			if (qName.equals("contact")){
				contact = new Contact(); 
				// 因为 id 属性在 contact 标签中,所以可以直接获取 id 属性的值,封装进 contact 对象中
				contact.setId(attributes.getValue("id"));
			}
			
		}
		
		/**
		 * 读到 结束标签 时调用
		 */
		@Override
		public void endElement(String uri, String localName, String qName) throws SAXException {
			// 设置为空是为了避免把空格换行设置到对象的属性中
			currTag = "";
			
			// 读到 contact 结束标签时,将 contact 对象存入集合中
			if (qName.equals("contact")){
				lists.add(contact);
			}
		}
		
		/**
		 * 读到 文本内容 时调用
		 */
		@Override
		public void characters(char[] ch, int start, int length) throws SAXException {
			// 读取到当前文本的内容
			String text = new String(ch, start, length);
			
			if (currTag.equals("name")){
				contact.setName(text);
			}

			if (currTag.equals("age")){
				contact.setAge(text);
			}

			if (currTag.equals("phone")){
				contact.setPhone(text);
			}

			if (currTag.equals("email")){
				contact.setEmail(text);
			}

			if (currTag.equals("qq")){
				contact.setQq(text);
			}
			
		}
	}
}



其中 ./src/contact.xml 为:

<?xml version="1.0" encoding="utf-8"?>
<contactList>
	<contact id="001" name="eric">
		<name>张三</name>
		<age>20</age>
		<phone>134222223333</phone>
		<email>[email protected]</email>
		<qq>432221111</qq>
	</contact>
	<contact id="002">
		<name>李四</name>
		<age>20</age>
		<phone>134222225555</phone>
		<email>[email protected]</email>
		<qq>432222222</qq>
	</contact>
	<abc></abc>
</contactList>

其中 Javabean(Contact.java)为:

package com.demo.a_dom4j;

public class Contact {
	private String id;
	private String name;
	private String age;
	private String phone;
	private String email;
	private String qq;

	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 getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getQq() {
		return qq;
	}

	public void setQq(String qq) {
		this.qq = qq;
	}

	@Override
	public String toString() {
		return "Contact [id=" + id + ", name=" + name + ", age=" + age + ", phone=" + phone + ", email=" + email
				+ ", qq=" + qq + "]";
	}

}

猜你喜欢

转载自blog.csdn.net/qq_29331365/article/details/89923251