XML文档示例:
<people>
<person personId="E01">
<name>Tony Blairname>
<address>10 Downing Street,London,UKaddress>
<tel>(061) 98765tel>
<fax>(061) 98765fax>
<email>[email protected]email>
person>
<person personId="E02">
<name>Tony Blairname>
<address>10 Downing Street,London,UKaddress>
<tel>(061) 98765tel>
<fax>(061) 98765fax>
<email>[email protected]email>
person>
people>
(1)充当显示数据(以XML充当显示层)
(2)存储数据(存储层)的功能
(3)以XML描述数据,并在联系服务器与系统的其余部分之间传递
从某种角度讲,XML是数据封装和信息传递技术。
SAX是Simple Apl for XML的缩写
SAX API中主要有四种处理事件的接口,ContenHandler、DTDHandler、EntiyResolver和ErrorHandler,由于DefaultHandler实现了这四个事件处理器接口。所以我们只需要继承DefaultHandler类就可以。
package com.lili.xmlAndJson;
/**
* @author: QiJingJing
* @create: 2021/7/17
*/
public class Person {
private String personId;
private String name;
private String address;
private String tel;
private String fax;
private String email;
public Person(){
}
public Person(String personId, String name, String address, String tel, String fax, String email) {
this.personId = personId;
this.name = name;
this.address = address;
this.tel = tel;
this.fax = fax;
this.email = email;
}
public String getPersonId() {
return personId;
}
public void setPersonId(String personId) {
this.personId = personId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Person{" +
"personId='" + personId + '\'' +
", name='" + name + '\'' +
", address='" + address + '\'' +
", tel='" + tel + '\'' +
", fax='" + fax + '\'' +
", email='" + email + '\'' +
'}';
}
}
在测试类里面创建SAX解析器工厂对象
// 1.创建一个SAX解析器工厂对象
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
使用解析器工厂创建解析器实例
//2.通过工厂对象创建SAX解析器
SAXParser saxParser = saxParserFactory.newSAXParser();
写一个事件侦听器类,需要继承DefaultHandler类,然后重写其中五个方法,每个方法的用途我已经标注
package com.lili.xmlAndJson;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
/**
* @author: QiJingJing
* @create: 2021/7/17
*/
public class PersonHandler extends DefaultHandler {
private List<Person> personList;
private Person p; // 当前正在解析的对象
private String tag;//用于记录当前正在解析的标签名
public List<Person> getPersonList() {
return personList;
}
// 开始解析文档时调用
@Override
public void startDocument() throws SAXException {
super.startDocument();
personList = new ArrayList<>();
System.out.println("开始解析文档");
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("解析文档结束");
}
// 解析开始元素时使用
/**
* @param uri 命名空间
* @param localName 不带前缀的标签名
* @param qName 带前缀的标签名
* @param attributes 当前标签的属性集合
* @return: void
* @author: QijingJing
* @date: 2021/7/17
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if ("person".equals(qName)) {
p = new Person();
String personId = attributes.getValue("personId");
p.setPersonId(personId);
}
tag = qName;
}
// 解析结束元素时使用
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if ("person".equals(qName)) {
personList.add(p);
}
tag = null;
}
// 解析文本内容时调用
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
if (tag != null) {
if ("name".equals(tag)) {
p.setName(new String(ch, start, length));
} else if ("address".equals(tag)) {
p.setAddress(new String(ch, start, length));
} else if ("tel".equals(tag)) {
p.setTel(new String(ch, start, length));
} else if ("fax".equals(tag)) {
p.setFax(new String(ch, start, length));
} else if ("email".equals(tag)) {
p.setEmail(new String(ch, start, length));
}
}
}
}
在测试类里面创建一个侦听器对象,给出XML的地址,然后开始解析
package com.lili.xmlAndJson;
import org.junit.Test;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author: QiJingJing
* @create: 2021/7/17
*/
public class XmlTest {
@Test
public void test() throws ParserConfigurationException, SAXException, IOException {
// 1.创建一个SAX解析器工厂对象
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//2.通过工厂对象创建SAX解析器
SAXParser saxParser = saxParserFactory.newSAXParser();
//3.创建一个数据处理器(需要我们自己来编码)
PersonHandler personHandler = new PersonHandler();
// 4.开始解析
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/lili/xmlAndJson/person.xml");
saxParser.parse(is,personHandler);
List<Person> personList = personHandler.getPersonList();
personList.forEach(System.out::println);
}
}
输出如下:
开始解析文档
解析文档结束
Person{personId='E01', name='Tony Blair', address='10 Downing Street,London,UK', tel='(061) 98765', fax='(061) 98765', email='[email protected]'}
Person{personId='E02', name='Tony Blair', address='10 Downing Street,London,UK', tel='(061) 98765', fax='(061) 98765', email='[email protected]'}
Process finished with exit code 0
1.基于事件驱动
2.顺序读取,速度快
3.不能任意读取节点(灵活性差)
4.解析占用内存小
5.SAX更适用于在性能要求更高的设备上使用(Android开发中)