Java SAX 解析 XML

迈不过友情╰ 2022-07-14 01:53 352阅读 0赞

与 DOM 建立树形结构的方式不同,SAX 采用事件模型来解析 XML 文档,是解析 XML 文档的一种更快速、更轻量的方法。

利用 SAX 可以对 XML 文档进行有选择的解析和访问,而不必像 DOM 那样加载整个文档,因此它对内存的要求较低。

但 SAX 对 XML 文档的解析为一次性读取,不创建任何文档对象,很难同时访问文档中的多处数据。

在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode

如下面代码片段

  1. <root>
  2. <person>
  3. <username>张三</username>
  4. <age>22</age>
  5. <idcard>320105197903082216</idcard>
  6. </person>
  7. </root>

其中<root>、<person>属于ElementNode,张三、22属于TextNode

然后还要知道SAX解析XML的执行顺序,看下面这张图

这里写图片描述

xml文件被Sax解析器载入,由于Sax解析是按照xml文件的顺序来解析,首先会调用startDocument()方法

当读入的时候,由于它是ElementNode,所以会调用startElement(String uri, String localName, String qName,

Attributes attributes)方法,其中第三个参数是节点的名称,

图中3的位置会调用characters(char[] ch, int start, int length)方法虽然是空白,Sax解析器也会把它认为是一个TextNode,

由于空白不是我们想要的数据,我们需要的是节点下的文本信息,所以这就要定义一个标识来记录上一节点的名称

在characters()方法中,判断当前节点是不是username,如果是,就取出里面的文本信息

简单概括一下执行顺序

  • 1、startDocument
  • 2、startElement <root>
  • 3、characters 空白
  • 4、startElement <person>
  • 5、characters 空白
  • 6、startElement <username>
  • 7、characters 张三
  • 8、endElement </username>

首先定义Person类,封装Person对象

  1. public class Person {
  2. private String username;
  3. private String age;
  4. private String idcard;
  5. public String getUsername() {
  6. return username;
  7. }
  8. public void setUsername(String username) {
  9. this.username = username;
  10. }
  11. public String getAge() {
  12. return age;
  13. }
  14. public void setAge(String age) {
  15. this.age = age;
  16. }
  17. public String getIdcard() {
  18. return idcard;
  19. }
  20. public void setIdcard(String idcard) {
  21. this.idcard = idcard;
  22. }
  23. public String toString() {
  24. StringBuffer buf = new StringBuffer();
  25. buf.append("username: " + username);
  26. buf.append(", age: " + age);
  27. buf.append(", idcard: " + idcard);
  28. return buf.toString();
  29. }
  30. }

SAX解析代码如下:

  1. import java.io.File;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.xml.parsers.SAXParser;
  5. import javax.xml.parsers.SAXParserFactory;
  6. import org.xml.sax.Attributes;
  7. import org.xml.sax.SAXException;
  8. import org.xml.sax.helpers.DefaultHandler;
  9. import com.home.bean.Person;
  10. public class SaxParseService extends DefaultHandler {
  11. private List<Person> persons = null; // 保存Person
  12. private Person person = null;
  13. private String preTag = null;// 作用是记录解析时的上一个节点名称
  14. public List<Person> getPersons(File file) throws Exception {
  15. SAXParserFactory factory = SAXParserFactory.newInstance();
  16. SAXParser parser = factory.newSAXParser();
  17. SaxParseService handler = new SaxParseService();
  18. parser.parse(file, handler);
  19. return handler.getPersons();
  20. }
  21. public List<Person> getPersons() {
  22. return persons;
  23. }
  24. @Override
  25. public void startDocument() throws SAXException {
  26. persons = new ArrayList<Person>();
  27. }
  28. @Override
  29. public void startElement(String uri, String localName, String qName,
  30. Attributes attributes) throws SAXException {
  31. if ("person".equals(qName)) {
  32. person = new Person(); // 如果节点为<person> 就实例化一个对象
  33. }
  34. preTag = qName;// 将正在解析的节点名称赋给preTag
  35. }
  36. @Override
  37. public void endElement(String uri, String localName, String qName)
  38. throws SAXException {
  39. if ("person".equals(qName)) {
  40. persons.add(person);
  41. person = null;
  42. }
  43. preTag = null; // 当解析结束时设置为空,以便执行characters()方法时进行匹配
  44. }
  45. @Override
  46. public void characters(char[] ch, int start, int length)
  47. throws SAXException {
  48. if (preTag != null) {
  49. String content = new String(ch, start, length);
  50. if ("username".equals(preTag)) {
  51. person.setUsername(content);
  52. } else if ("age".equals(preTag)) {
  53. person.setAge(content);
  54. } else if ("idcard".equals(preTag)) {
  55. person.setIdcard(content);
  56. }
  57. }
  58. }
  59. public static void main(String[] args) {
  60. SaxParseService sax = new SaxParseService();
  61. File file = new File("person.xml");
  62. try {
  63. List<Person> persons = sax.getPersons(file);
  64. for (Person person : persons) {
  65. System.out.println(person.toString());
  66. }
  67. } catch (Exception e) {
  68. e.printStackTrace();
  69. }
  70. }
  71. }

作者:itmyhome

发表评论

表情:
评论列表 (有 0 条评论,352人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SAX解析XML

    *下面是SAX解析XML的示例,包括三个文件employee.xml、Employee.java、SaxEmployee.java** **1.被解析的employee...

    相关 SAX解析XML

    SAX(Simple API for XML)也是一种解析 XML 文件的方法,它虽然不是官方标准,但它是 XML 的事实标准,大部分 XML 解析器都支持它。 SAX 与

    相关 Java SAX 解析 XML

    与 DOM 建立树形结构的方式不同,SAX 采用事件模型来解析 XML 文档,是解析 XML 文档的一种更快速、更轻量的方法。 利用 SAX 可以对 XML 文档进行有选择的

    相关 Java——SAX解析XML文件

    SAX适用于只读取XML文件内容的情况,因为SAX是一种边读边解析的模式,所以不需要直接将XML文件直接塞入内存,读取速度也更快,但是只能读。 SAX解析主要有两个部分:①

    相关 SAX解析XML

    SAX(Simple API for XML)也是一种解析 XML 文件的方法,它虽然不是官方标准,但它是 XML 的事实标准,大部分 XML 解析器都支持它。 SAX ...