SAX解析XML
程序员文章站
2022-05-28 08:31:37
...
下面是SAX解析XML的示例,包括三个文件employee.xml、Employee.java、SaxEmployee.java
1.被解析的employee.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE employees [
<!ELEMENT employees (employee*)>
<!ELEMENT employee (name,age,gender,email,salary)>
<!ATTLIST employee id CDATA #IMPLIED>
<!ATTLIST employee depName CDATA #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT gender (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT salary (#PCDATA)>
]>
<employees>
<employee id="1" depName="教学部">
<name>tom</name>
<age>20</age>
<gender>male</gender>
<email>[email protected]</email>
<salary>10k</salary>
</employee>
<employee id="2" depName="教学部">
<name>jack</name>
<age>30</age>
<gender>female</gender>
<email>[email protected]</email>
<salary>8k</salary>
</employee>
<employee id="3" depName="市场部">
<name>rose</name>
<age>25</age>
<gender>female</gender>
<email>[email protected]</email>
<salary>5k</salary>
</employee>
<employee id="4" depName="教学管理部">
<name>mark</name>
<age>30</age>
<gender>male</gender>
<email>[email protected]</email>
<salary>5k</salary>
</employee>
</employees>
2.Employee.java文件
package exercise;
public class Employee {
private int id;
private String depName;
private String name;
private int age;
private String gender;
private String email;
private String salary;
public Employee() {
}
public Employee(int id, String depName, String name, int age, String gender, String email, String salary) {
super();
this.id = id;
this.depName = depName;
this.name = name;
this.age = age;
this.gender = gender;
this.email = email;
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", depName=" + depName + ", name=" + name + ", age=" + age + ", gender=" + gender
+ ", email=" + email + ", salary=" + salary + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDepName() {
return depName;
}
public void setDepName(String depName) {
this.depName = depName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
}
3.SaxEmployee.java实现解析
package exercise;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
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解析,将employee.xml中的employee对象存放到list中
* @author Attention
*
*/
public class SaxEmployee {
public static void main(String[] args) throws Exception {
//1.先创建解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.利用工厂创建一个解析器
SAXParser parser = factory.newSAXParser();
//3.调用解析方法,解析文件,该方法有两个参数,第一个参数是你要解析的文件,第二个参数是处理类
File file = new File("src/exercise/employee.xml");
Handler handler = new Handler();
parser.parse(file, handler);
}
}
/**
* 创建一个类继承默认处理类,实现里面具体的解析方法
* 前面说过SAX是基于事件的解析,遇到开始标签、结束标签、文本,空文本会触发事件
* 我们就是要写触发事件后具体的执行过程,这也是SAX比较复杂的地方
* 里面有几个很关键的方法:
* 1.startDocument()
* 2.endDocument()
* 3.startElement()
* 4.endElement()
* 5.characters()
* 实现这几个方法就可以对xml文件进行解析了,当然1和2两个方法可以不实现
*/
class Handler extends DefaultHandler{
//首先我们先创建一个List容器用来存放Employee对象,我们在startDocument()方法中进行初始化
private List<Employee> list = null;
//用来存放当前的标签名
private String tagName = null;
//定义一个Employee对象
private Employee employee = null;
@Override
public void startDocument() throws SAXException {
System.out.println("============开始解析文档============");
list = new ArrayList<>();
}
@Override
public void endDocument() throws SAXException {
System.out.println("============解析文档结束============");
//执行到这个方法,说明文档已经解析完毕,我们在这里将list容器中的内容打印出来,测试一下我们方法是否有误
//当前也可以给List提供get()函数,在外面拿取
for(Employee e : list) {
System.out.println(e);
}
}
//开始标签,当遇到开始标签会触发该方法
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equals("employee")) { //说明拿到一个Employee对象
employee = new Employee(); //我们就创建一个对象
String id = attributes.getValue("id"); //获取到两个属性值
String depName = attributes.getValue("depName");
employee.setId(Integer.parseInt(id)); //将当前取到的值赋给当前对象
employee.setDepName(depName);
}else {
tagName = qName;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("employee")) { //此时说明一个对象已经解析完,我们就将当前对象存放到容器中
list.add(employee);
}else {
//因为SAX解析也会识别空文本,所以每次遇到尾标签,需要将tagName值空,避免,将当前的值被空文本给覆盖掉
tagName = null;
}
}
//当前文本内容
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//构建当前读取到文本内容
String msg = new String(ch,start,length);
//tagName存放这当前的qName,判断当前拿取到的是那个值
if(tagName.equals("name")) {
employee.setName(msg);
}else if(tagName.equals("age")) {
employee.setAge(Integer.parseInt(msg));
}else if(tagName.equals("gender")) {
employee.setGender(msg);
}else if(tagName.equals("email")) {
employee.setEmail(msg);
}else if(tagName.equals("salary")) {
employee.setSalary(msg);
}
}
}