SAX解析简介
SAX(Simple API for XML)是一种以事件驱动的XML API,是XML解析的方式之一。DOM解析会将XML全部加载到内存中,再进行解析。SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点。
SAX解析步骤
SAX解析的核心步骤有如下几步:
- 得到xml文件对应的资源,可以是xml的输入流,文件和uri
- 得到SAX解析工厂(SAXParserFactory)
- 由解析工厂生产一个SAX解析器(SAXParser)
- 传入输入流和handler给解析器,调用parse()解析
SAX解析案例
1、xml文件
<?xml version="1.0" encoding="utf-8"?>
<contract>
<member id="001">
<name>张三</name>
<age>18</age>
<tel>110</tel>
</member>
<member id="002">
<name>李四</name>
<age>18</age>
<tel>120</tel>
</member>
</contract>
2、JavaBean
public class Member {
private Integer id;
private String name;
private Integer age;
private Integer tel;
public Member() {
}
public Member(Integer id, String name, Integer age, Integer tel) {
this.id = id;
this.name = name;
this.age = age;
this.tel = tel;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getTel() {
return tel;
}
public void setTel(Integer tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Member{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", tel=" + tel +
'}';
}
}
3、新建一个类MyParseHandler.java,该类继承DefaultHandler.java,并重写DefaultHandler类中的五个核心方法。
-
startDocument():文档解析开始时调用,该方法只会调用一次
-
startElement(String uri, String localName, String qName, Attributes attributes):标签解析开始时调用
uri:xml文档的命名空间 localName:标签的名字 qName:带命名空间的标签的名字 attributes:标签的属性集
-
characters(char[] ch, int start, int length):解析标签的内容的时候调用
ch:当前读取到的TextNode(文本节点)的字节数组 start:字节开始的位置,为0则读取全部 length:当前TextNode的长度
-
endElement(String uri, String localName, String qName):标签解析结束后调用
-
endDocument():文档解析结束后调用,该方法只会调用一次
MyParseHandler类的具体代码如下
public class MyDefaultHandler extends DefaultHandler {
private List<Member> members = new ArrayList<>();
private Member member;
String value = null;
@Override
public void startDocument() throws SAXException {
System.out.println("SAX解析开始");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
/*
* qName是当前解析的节点名称
* attributes是当前解析的节点的所有属性
*/
if ("member".equals(qName)) {
//如果当前解析的是member节点,则创建一个Member对象,并取得属性值(id)
member = new Member();
String idValue = attributes.getValue("id");
member.setId(Integer.parseInt(idValue));
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
value = new String(ch,start,length);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("name".equals(qName)) {
member.setName(value);
}else if ("age".equals(qName)) {
member.setAge(Integer.parseInt(value));
}else if ("tel".equals(qName)) {
member.setTel(Integer.parseInt(value));
}else if ("member".equals(qName)) {
members.add(member);
member = null;
}
}
@Override
public void endDocument() throws SAXException {
System.out.println("SAX解析结束");
}
public List<Member> getMembers() {
return this.members;
}
}
测试类代码如下
public class TestDemoI {
public static void main(String[] args) throws Exception{
//设置要读取的文件对象
File file = new File("E:" + File.separator + "Telephone.xml");
// 通过SAXParserFactory的静态方法newInstance()获取SAXParserFactory的实例
SAXParserFactory factory = SAXParserFactory.newInstance();
// 通过SAXParserFactory的实例的newSAXParser()方法获取SAXParser实例
SAXParser parser = factory.newSAXParser();
// 定义一个自己的Handler类,继承DefaultHandler
MyDefaultHandler handler = new MyDefaultHandler();
parser.parse(file, handler);
List<Member> members = handler.getMembers();
System.out.println(members);
}
}
输出结果如下
SAX解析开始
SAX解析结束
[Member{id=1, name='张三', age=18, tel=110}, Member{id=2, name='李四', age=19, tel=120}]
版权声明:本文为qq_36025972原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。