9.2 Sax方式对xml数据进行解析

介绍

  1. xml: 可扩展标记语言,作为数据的一种存储格式或用于存储软件的参数,程序解析此配置文件,就可以达到不修改代码就能更改程序的目的。
  2. xml数据示例
<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>猴子</name>
		<age>500</age>
	</person>
	<person>
		<name>八戒</name>
		<age>300</age>
	</person>
</persons>

      第一行数据为声明部分。
3. 解析方式

  • Dom方式:将整个xml文档加载到内存中,然后进行处理。缺点显然是不适合处理大文件。
  • Sax方式:从文档头开始以流的方式不断向下进行解析。

SAX方式解析流程

流程
  1. 获取解析工厂
  2. 从解析工厂获取解析器
  3. 编写处理器
  4. 加载文档Document注册处理器
  5. 进行解析, 从当前的类加载器获取文档
  • 在使用时第1、2、4、5步可直接复制粘贴,主要是自己动手实现第3步。
示例

代码:

import java.io.IOException;

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

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

/**
 * 熟悉SAX解析流程
 * 1. 获取解析工厂
 * 2. 从解析工厂获取解析器
 * 3. 编写处理器 
 * 4. 加载文档Document注册处理器
 * 5. 进行解析, 从当前的类加载器获取文档
 * @author dxt
 *
 */
public class XmlTest01 {
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
		//SAX解析
		//1. 获取解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//2. 从解析工厂获取解析器
		SAXParser parse = factory.newSAXParser();
		
		//3. 编写处理器,就是去编写PHandler类 
		
		//4. 加载文档Document注册处理器
		PHandler handler = new PHandler();	//其中PHandler是我们自己写的
		//5. 进行解析, 从当前的类加载器获取xmlwendang
		parse.parse(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("dxt/basic/p.xml"), handler);
	}
}

class PHandler extends DefaultHandler{
	@Override
	public void startDocument() throws SAXException{
		System.out.println("------文档解析开始------");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes){
		//开始解析元素,只关注qName, qName为标签
		System.out.println(qName + "--->解析开始");
	}
	
	@Override
	public void characters(char[] ch, int start, int length){
		/*
		 * 在此方法中获取相应标签内的内容
		 * 有一点需要注意的是:xml中的换行、缩进产生的空格 会被识别为标签内的内容
		 * 在使用时,需要处理换行 和 缩进产生的空格
		 */
		String contents = new String(ch, start, length).trim();	//trim()去掉字符串前后的空格
		if(contents.length() > 0){
			System.out.println("内容为:" + contents);
		}else{
			System.out.println("空----空");
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName){
		//解析元素结束
		System.out.println(qName + "--->解析结束");
	}
	
	@Override
	public void endDocument() throws SAXException{
		System.out.println("------文档解析结束------");
	}
}

数据:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>猴子</name>
		<age>500</age>
	</person>
</persons>

结果:
p

注意点

      第3步编写处理器在主程序流程之中并没有代码体现。我们重写的处理器继承类DefaultHandler。
      在处理过程中注意标签间的换行和空格。

SAX方式数据处理

数据
<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>猴子</name>
		<age>500</age>
	</person>
	<person>
		<name>八戒</name>
		<age>300</age>
	</person>
</persons>
代码

Person类:

/**
 * Person类
 * 为了处理xml数据
 * @author dxt
 *
 */
public class Person {
	private String name;
	private int age;
	
	public Person(){}
	public Person(String name, int age){
		super();
		this.name = name;
		this.age = age;
	}
	
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return this.name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return this.age;
	}
}

处理代码:

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

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

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

/**
 * 使用SAX处理xml数据
 * 
 * @author dxt
 *
 */
public class XmlTest02 {
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
		//1. 获取解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//2. 从解析工厂获取解析器
		SAXParser parser = factory.newSAXParser();
		
		//3. 编写处理器
		
		//4. 加载文档注册处理器
		PersonHandler phandler = new PersonHandler();
		
		//5. 进行解析
		parser.parse(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("dxt/basic/p.xml"), phandler);
		
		// 获取数据 并打印数据
		List<Person> persons = phandler.getPersons();
		for(Person p:persons){
			System.out.println(p.getName() + "--" + p.getAge());
		}
	}
}

class PersonHandler extends DefaultHandler{
	private List<Person> persons;
	private Person p;
	private String tag; 	//存储操作的标签
	
	public List<Person> getPersons(){
		return persons;
	}
	
	@Override
	public void startDocument(){
		persons = new ArrayList<Person>();
		System.out.println("-------文档解析开始-------");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes){
		//遇到person开始标签,则初始化一个person
		if(null != qName){
			tag = qName;	//存储标签名
			
			if(tag.equals("person")){
				p = new Person();
			}
		}
	}
	
	public void characters(char[] ch, int start, int length){
		String contents = new String(ch, start, length).trim();
		
		if(tag != null){
			if(tag.equals("name")){
				p.setName(contents);
			}else if(tag.equals("age")){
				p.setAge(Integer.valueOf(contents));
			}
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName){
		//遇到person结束标签,则说明此p的信息已处理完毕,将其加入队列
		if(null != qName){
			if(qName.equals("person")){
				persons.add(p);
			}
		}
		tag = null;
	}
	
	@Override
	public void endDocument(){
		System.out.println("-------文档解析结束-------");
	}
}
结果

p2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值