Java SAX 解析器示例

SAX 解析器与 DOM 解析器不同,因为它不会将完整的 XML 加载到内存中,并连续阅读 xml 文档。

萨克斯帕塞尔

sax parser, sax parser example, java sax parser javax.xml.parsers.SAXParser provides method to parse XML document using event handlers. This class implements XMLReader interface and provides overloaded versions of parse() methods to read XML document from File, InputStream, SAX InputSource and String URI. The actual parsing is done by the Handler class. We need to create our own handler class to parse the XML document. We need to implement org.xml.sax.ContentHandler interface to create our own handler classes. This interface contains callback methods that receive notification when an event occurs. For example StartDocument, EndDocument, StartElement, EndElement, CharacterData etc. org.xml.sax.helpers.DefaultHandler provides default implementation of ContentHandler interface and we can extend this class to create our own handler. It's advisable to extend this class because we might need only a few of the methods to implement. Extending this class will keep our code cleaner and maintainable.

Sax Parser 示例

现在让我们跳到SAX分析器示例程序,我将在稍后详细解释不同的功能。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<Employees>
 3    <Employee id="1">
 4    	<age>29</age>
 5    	<name>Pankaj</name>
 6    	<gender>Male</gender>
 7    	<role>Java Developer</role>
 8    </Employee>
 9    <Employee id="2">
10    	<age>35</age>
11    	<name>Lisa</name>
12    	<gender>Female</gender>
13    	<role>CEO</role>
14    </Employee>
15    <Employee id="3">
16    	<age>40</age>
17    	<name>Tom</name>
18    	<gender>Male</gender>
19    	<role>Manager</role>
20    </Employee>
21    <Employee id="4">
22    	<age>25</age>
23    	<name>Meghna</name>
24    	<gender>Female</gender>
25    	<role>Manager</role>
26    </Employee>
27</Employees>

因此,我们有一个 XML 文件存储在文件系统中的某个地方,通过查看它,我们可以得出结论,它包含员工列表. 每个员工都有id属性和字段年龄,名称,性别角色

 1package com.journaldev.xml;
 2
 3public class Employee {
 4    private int id;
 5    private String name;
 6    private String gender;
 7    private int age;
 8    private String role;
 9
10    public int getId() {
11        return id;
12    }
13    public void setId(int id) {
14        this.id = id;
15    }
16    public String getName() {
17        return name;
18    }
19    public void setName(String name) {
20        this.name = name;
21    }
22    public String getGender() {
23        return gender;
24    }
25    public void setGender(String gender) {
26        this.gender = gender;
27    }
28    public int getAge() {
29        return age;
30    }
31    public void setAge(int age) {
32        this.age = age;
33    }
34    public String getRole() {
35        return role;
36    }
37    public void setRole(String role) {
38        this.role = role;
39    }
40
41    @Override
42    public String toString() {
43        return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +
44                " Role=" + this.role;
45    }
46
47}

让我们创建自己的 SAX Parser Handler 类,扩展到 DefaultHandler类。

 1package com.journaldev.xml.sax;
 2
 3import java.util.ArrayList;
 4import java.util.List;
 5
 6import org.xml.sax.Attributes;
 7import org.xml.sax.SAXException;
 8import org.xml.sax.helpers.DefaultHandler;
 9
10import com.journaldev.xml.Employee;
11
12public class MyHandler extends DefaultHandler {
13
14    // List to hold Employees object
15    private List<Employee> empList = null;
16    private Employee emp = null;
17    private StringBuilder data = null;
18
19    // getter method for employee list
20    public List<Employee> getEmpList() {
21    	return empList;
22    }
23
24    boolean bAge = false;
25    boolean bName = false;
26    boolean bGender = false;
27    boolean bRole = false;
28
29    @Override
30    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
31
32    	if (qName.equalsIgnoreCase("Employee")) {
33    		// create a new Employee and put it in Map
34    		String id = attributes.getValue("id");
35    		// initialize Employee object and set id attribute
36    		emp = new Employee();
37    		emp.setId(Integer.parseInt(id));
38    		// initialize list
39    		if (empList == null)
40    			empList = new ArrayList<>();
41    	} else if (qName.equalsIgnoreCase("name")) {
42    		// set boolean values for fields, will be used in setting Employee variables
43    		bName = true;
44    	} else if (qName.equalsIgnoreCase("age")) {
45    		bAge = true;
46    	} else if (qName.equalsIgnoreCase("gender")) {
47    		bGender = true;
48    	} else if (qName.equalsIgnoreCase("role")) {
49    		bRole = true;
50    	}
51    	// create the data container
52    	data = new StringBuilder();
53    }
54
55    @Override
56    public void endElement(String uri, String localName, String qName) throws SAXException {
57    	if (bAge) {
58    		// age element, set Employee age
59    		emp.setAge(Integer.parseInt(data.toString()));
60    		bAge = false;
61    	} else if (bName) {
62    		emp.setName(data.toString());
63    		bName = false;
64    	} else if (bRole) {
65    		emp.setRole(data.toString());
66    		bRole = false;
67    	} else if (bGender) {
68    		emp.setGender(data.toString());
69    		bGender = false;
70    	}
71    	
72    	if (qName.equalsIgnoreCase("Employee")) {
73    		// add Employee object to list
74    		empList.add(emp);
75    	}
76    }
77
78    @Override
79    public void characters(char ch[], int start, int length) throws SAXException {
80    	data.append(new String(ch, start, length));
81    }
82}

MyHandler 包含员工对象的列表,作为一个只使用 getter 方法的字段。在事件处理方法中添加了员工对象。

SAX 解析方法 解析方法

SAXParser开始解析文档,当发现任何起始元素时,称为startElement()方法。我们正在解析这种方法,以设定将用于识别元素的Boolean变量。我们也使用这种方法创建新的员工对象,每次找到员工开始元素。 检查ID属性如何在这里读取以设置员工对象id字段。 当 SAXParser在元素中找到字符数据时,称为characters()方法。 请注意,SAX分析师可能会将数据分成多个片段,并使用Callcharacters()方法多次(读取ContentHandler字符类类()方法文档)。 这就是为什么我们正在使用StringBuilder来使用这个数据使用append()方法来保持这个数据。 Element Build是我们

 1package com.journaldev.xml.sax;
 2
 3import java.io.File;
 4import java.io.IOException;
 5import java.util.List;
 6
 7import javax.xml.parsers.ParserConfigurationException;
 8import javax.xml.parsers.SAXParser;
 9import javax.xml.parsers.SAXParserFactory;
10
11import org.xml.sax.SAXException;
12
13import com.journaldev.xml.Employee;
14
15public class XMLParserSAX {
16
17    public static void main(String[] args) {
18    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
19    try {
20        SAXParser saxParser = saxParserFactory.newSAXParser();
21        MyHandler handler = new MyHandler();
22        saxParser.parse(new File("/Users/pankaj/employees.xml"), handler);
23        //Get Employees list
24        List<Employee> empList = handler.getEmpList();
25        //print employee information
26        for(Employee emp : empList)
27            System.out.println(emp);
28    } catch (ParserConfigurationException | SAXException | IOException e) {
29        e.printStackTrace();
30    }
31    }
32
33}

以下是上述方案的结果。

1Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer
2Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO
3Employee:: ID=3 Name=Tom Age=40 Gender=Male Role=Manager
4Employee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager

「SAXParserFactory」提供工厂方法来获取「SAXParser」实例. 我们正在将文件对象传输到分析方法以及MyHandler实例来处理回调事件。SAXParser在开始时有点困惑,但如果你正在处理一个大型XML文档,它提供了比DOM Parser更有效的方式来读取XML。

您可以从我们的 GitHub 存储库下载该项目。

Reference: SAXParser, DefaultHandler

Published At
Categories with 技术
Tagged with
comments powered by Disqus