解析流程及原理

  1. //根据xml的标签创建对应的实体类
  2. //创建SAX工厂
  3. //从工厂实例获取SAX解析器
  4. //创建Handler子类并new
  5. //重写此子类:将标签下对应的内容写入实体类中
  6. //解析

SAX解析xml文件只走一次,一次就解析完成,解析顺序是从上到下,逐行解析,解析标签,然后解析标签之间的内容(即使是空白、换行符都要解析出来),然后再解析标签。

SAX可以识别开始标签与结束标签,所以我们可以在startElement()与endElement()方法里很方便的做一些事情。

characters()方法用来读取两个相邻标签之间的内容(并不是读成对标签之间的内容),即使是空白,也读出来。例如:</person> </persons>,我们可以使用trim()将空白字符消除

使用一个变量tag来存储标签名,可以在characters()方法中对应当前的标签名,方便判断标签并读取数据。

案例演示

将下面xml使用SAX解析,将结果存放在实体类中。

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>周杰伦</name>
		<fans>3000w</fans>
	</person>
	<person>
		<name>蔡依林</name>
		<fans>2000w</fans>
	</person>
</persons>

  

代码

其中 show方法不是重写方法,是自定义方法。

实体类:

package _20191224_review;
/**
 * person.xml中Person标签的实体
*/
public class Person {
	private String name;
	private String fans;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getFans() {
		return fans;
	}
	public void setFans(String fans) {
		this.fans = fans;
	}
}

  

解析流程:

package _20191224_review;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
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解析
 * 代码:36
 */
public class TestXmlSAX {
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//从工厂中获取SAX
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//从SAX中获取解析器
		SAXParser parser = factory.newSAXParser();
		//创建Handler子类,并实例化
		PersonHandler handler = new PersonHandler();
		//重写该类中的必要方法
		//解析
		parser.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("_20191224_review/person.xml"),handler);
		//尝试获取数据
		handler.show();
	}
}

class PersonHandler extends DefaultHandler{
	private List<Person> persons;
	private String tag;
	private Person person;
	public PersonHandler() {
		persons = new ArrayList<>();
	}
	@Override
	public void startDocument() throws SAXException {
		System.out.println("解析文档开始了");
	}
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		tag = qName;
		System.out.println("元素开始-->"+tag);
		if(tag.equals("person")) {
			person = new Person();
		}
	}
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		tag = qName;
		System.out.println("元素结束-->"+qName);
		if(tag.equals("person")) {
			persons.add(person);
		}
	}
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String content = new String(ch,start,length);
		if(content.trim().isEmpty()) {
			return;
		}
		System.out.println("tag "+tag+" 内容:"+content);
		if(tag.equals("name")) {
			person.setName(content);
		}
		if(tag.equals("fans")) {
			person.setFans(content);
		}
	}
	public void show() {
		Iterator it = persons.iterator();
		while(it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println("名字:"+p.getName()+" 粉丝数:"+p.getFans());
		}
	}
}

  

 

运行效果

02-11 09:15