解析XML——DOM、Pull、SAX

前端之家收集整理的这篇文章主要介绍了解析XML——DOM、Pull、SAX前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


读取XML主要有2种方法:DOM与SAX(Simple API for XML),在这里对这2种方法分别加以说明。

DOM(文档对象模型),为XML文档的解析定义了一组接口,解析器读入整个文档,然后构造一个驻留内存的树结构,然后代码就可以使用DOM接口来 操组整个树结构,其他点如下:

  • 优点:整个文档树都在内存当中,便于操作;支持删除修改、重新排列等多功能
  • 缺点:将整个文档调入内存(经常包含大量无用的节点),浪费时间和空间。
  • 使用场合:一旦解析了文档还需要多次访问这些数据,而且资源比较充足(如内存、cpu等)。

为了解决DOM解析XML引起的这些问题,出现了SAX。SAX解析XML文档为事件驱动。当解析器发现元素开始、元素结束,文本、文档的开始或者结束时,发送 事件,在程序中编写响应这些事件的代码,其特点如下:

  • 优点:不用事先调入整个文档,占用资源少。尤其在嵌入式环境中,极力推荐采用SAX进行解析XML文档。
  • 缺点:不像DOM一样将文档长期驻留在内存,数据不是持久的,事件过后,如没有保存数据,那么数据就会丢失。
  • 使用场合:机器性能有限,尤其是在嵌入式环境,如Android,极力推荐采用SAX进行解析XML文档。

大多数时间,使用 SAX 是比较安全的,并且 Android 提供了一种传统的 SAX 使用方法,以及一个便捷的 SAX 包装器。如果XML文档比较小,那么 DOM 可能是一种比较简单的方法。如果XML文档比较大,但只需要文档的一部分,则 XML Pull 解析器可能是更为有效的方法。最后对于编写 XML,Pull 解析器包也提供了一种便捷的方法。因此,无论我们的 XML 需求如何,Android 都能在一定程度上满足我们的需求。

下面我们详细介绍采用DOM的方法,读取XML文档的思路,这基本上与XML的结构是完全一样的。

首先加载XML文档(Document),

然后获 取文档的根结点(Element),

然后获取根结点中所有子节点的列表(NodeList),

然后使用再获取子节点列表中的需要读取的结点。

采用DOM读取XML文件,需要加载整个XML文件,在XML文件比较大的情况下,会导致Android设备内存紧张,为了避免这个问题,也可以采 用SAX的方法读取XML文件,不过SAX对结点的排序、增加结点等方面的操作相比DOM就有些复杂了。根据XML文件大小、数据处理的需求,选择合适的 读取的方法


XML代码如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <person>
  3. <student id="2">
  4. <name>张三</name>
  5. <age>23</age>
  6. </student>
  7. <student id="5">
  8. <name>李四</name>
  9. <age>25</age>
  10. </student>
  11. </person>

DOM解析:

java类代码

  1. package com.utils.parsexml;
  2.  
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. import javax.xml.parsers.DocumentBuilder;
  8. import javax.xml.parsers.DocumentBuilderFactory;
  9.  
  10. import org.w3c.dom.Document;
  11. import org.w3c.dom.Element;
  12. import org.w3c.dom.Node;
  13. import org.w3c.dom.NodeList;
  14.  
  15. /**
  16. * 使用DOM解析XML
  17. *
  18. * @author 伟
  19. *
  20. */
  21. public class DomXMLTools {
  22. public static List<Student> parseXML(InputStream is) throws Exception {
  23. List<Student> stus = new ArrayList<Student>();
  24. Student stu = null;
  25. // 创建一个document解析工厂
  26. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  27. DocumentBuilder db = dbf.newDocumentBuilder();
  28. Document doc = db.parse(is);
  29. Element element = doc.getDocumentElement();
  30. NodeList stuNodes = element.getElementsByTagName("student");
  31. for (int i = 0; i < stuNodes.getLength(); i++) {
  32. Element stuNode = (Element) stuNodes.item(i);
  33. stu = new Student();
  34. int id = Integer.parseInt(stuNode.getAttribute("id"));
  35. stu.setId(id);
  36. NodeList stuChilds = stuNode.getChildNodes();
  37. for (int j = 0; j < stuChilds.getLength(); j++) {
  38. Node childs = stuChilds.item(j);
  39. // 得到节点可能为回车或空格,所以必须判断
  40. if (childs.getNodeType() == Node.ELEMENT_NODE) {
  41. if (childs.getNodeName().equals("name")) {
  42. String name = childs.getFirstChild().getNodeValue();
  43. stu.setName(name);
  44. } else if (childs.getNodeName().equals("age")) {
  45. String ageStr = childs.getFirstChild().getNodeValue();
  46. int age = Integer.parseInt(ageStr);
  47. stu.setAge(age);
  48. }
  49. }
  50. }
  51. stus.add(stu);
  52. }
  53. return stus;
  54. }
  55. }

Pull解析:

java类代码

  1. package com.utils.parsexml;
  2.  
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. import org.xmlpull.v1.XmlPullParser;
  8. import org.xmlpull.v1.XmlPullParserFactory;
  9.  
  10. /**
  11. * 使用pull解析XML
  12. *
  13. * @author 伟
  14. *
  15. */
  16. public class PullXMLTools {
  17. public static List<Student> parseXML(InputStream is,String encode)
  18. throws Exception {
  19. List<Student> list = null;
  20. Student stu = null;
  21. // 新建一个XMLpull解析工厂
  22. XmlPullParserFactory xf = XmlPullParserFactory.newInstance();
  23. // 获得XML解析类的引用
  24. XmlPullParser xp = xf.newPullParser();
  25. xp.setInput(is,encode);
  26. // 获得事件的类型
  27. int type = xp.getEventType();
  28. while (type != XmlPullParser.END_DOCUMENT) {
  29. switch (type) {
  30. case XmlPullParser.START_DOCUMENT:
  31. // XML文档开始
  32. list = new ArrayList<Student>();
  33. break;
  34. case XmlPullParser.START_TAG:
  35. // 解析一个开始标签获取标签文本
  36. String tagName = xp.getName();
  37. if (tagName.equals("student")) {
  38. stu = new Student();
  39. // 获得属性
  40. int id = Integer.parseInt(xp.getAttributeValue(0));
  41. stu.setId(id);
  42. } else if (tagName.equals("name")) {
  43. // 获取节点内容
  44. String name = xp.nextText();
  45. stu.setName(name);
  46. } else if (tagName.equals("age")) {
  47. int age = Integer.parseInt(xp.nextText());
  48. stu.setAge(age);
  49. }
  50. break;
  51. case XmlPullParser.END_TAG:
  52. // 解析一个结束标签,并清空当前学生对象
  53. if (xp.getName().equals("student")) {
  54. list.add(stu);
  55. stu = null;
  56. }
  57. break;
  58. }
  59. // 重新获取事件类型
  60. type = xp.next();
  61. }
  62. return list;
  63. }
  64. }


SAX解析:

handler类:

  1. package com.utils.parsexml;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import org.xml.sax.Attributes;
  7. import org.xml.sax.SAXException;
  8. import org.xml.sax.helpers.DefaultHandler;
  9.  
  10. /**
  11. * 解析XML处理器
  12. *
  13. * @author 伟
  14. *
  15. */
  16. public class SaxHandler extends DefaultHandler {
  17. private List<Student> stus;
  18. private Student stu;
  19. private String currentTag;
  20. private String currentValue;
  21.  
  22. public List<Student> getStus() {
  23. return stus;
  24. }
  25.  
  26. @Override
  27. public void startDocument() throws SAXException {
  28. // 开始解析XML
  29. stus = new ArrayList<Student>();
  30. }
  31.  
  32. @Override
  33. public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {
  34. // 开始读取标签,qName为标签文本
  35. currentTag = qName;
  36. if (currentTag.equals("student")) {
  37. stu = new Student();
  38. if (attributes != null) {
  39. String idStr = attributes.getValue(0);
  40. int id = Integer.parseInt(idStr);
  41. stu.setId(id);
  42. }
  43. }
  44. }
  45.  
  46. @Override
  47. public void characters(char[] ch,int start,int length)
  48. throws SAXException {
  49. // 根据currentTag获取每个标签内容
  50. if (currentTag != null) {
  51. currentValue = new String(ch,start,length);
  52. // 确保value不是回车或者空字符
  53. if (currentValue != null && !currentValue.trim().equals("")
  54. && !currentValue.trim().equals("\n")) {
  55. if (currentTag.equals("name")) {
  56. stu.setName(currentValue);
  57. } else if (currentTag.equals("age")) {
  58. stu.setAge(Integer.parseInt(currentValue));
  59. }
  60. }
  61. }
  62. // 把当前节点对应的值清空
  63. currentTag = null;
  64. currentValue = null;
  65. }
  66.  
  67. @Override
  68. public void endElement(String uri,String qName)
  69. throws SAXException {
  70. // 遇到结束标签调用
  71. currentTag = qName;
  72. if (currentTag.equals("student")) {
  73. stus.add(stu);
  74. stu = null;
  75. }
  76. }
  77. }

java解析类:

  1. package com.utils.parsexml;
  2.  
  3. import java.io.InputStream;
  4. import java.util.List;
  5.  
  6. import javax.xml.parsers.SAXParser;
  7. import javax.xml.parsers.SAXParserFactory;
  8.  
  9. public class SaxXMLTools {
  10. public static List<Student> parseXML(InputStream is) throws Exception {
  11. List<Student> stus = null;
  12. // 创建一个XML解析处理器
  13. SaxHandler sh = new SaxHandler();
  14. // 创建一个SAX解析工厂
  15. SAXParserFactory spf = SAXParserFactory.newInstance();
  16. // 创建SAX解析器
  17. SAXParser sp = spf.newSAXParser();
  18. // 解析xml,将每个事件发给处理器
  19. sp.parse(is,sh);
  20. is.close();
  21. return sh.getStus();
  22. }
  23. }

实体类:

  1. package com.utils.parsexml;
  2.  
  3. public class Student {
  4. private int id;
  5. private String name;
  6. private int age;
  7.  
  8. public int getId() {
  9. return id;
  10. }
  11.  
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15.  
  16. public String getName() {
  17. return name;
  18. }
  19.  
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23.  
  24. public int getAge() {
  25. return age;
  26. }
  27.  
  28. public void setAge(int age) {
  29. this.age = age;
  30. }
  31.  
  32. public Student(int id,String name,int age) {
  33. this.id = id;
  34. this.name = name;
  35. this.age = age;
  36. }
  37.  
  38. public Student() {
  39. }
  40.  
  41. @Override
  42. public String toString() {
  43. return "Studnet [id=" + id + ",name=" + name + ",age=" + age + "]";
  44. }
  45. }


测试类:
  1. package com.utils.parsexml;
  2.  
  3. import java.io.InputStream;
  4. import java.util.List;
  5.  
  6. public class Test {
  7.  
  8. /**
  9. * @param args
  10. * @throws Exception
  11. */
  12. public static void main(String[] args) throws Exception {
  13. InputStream is = Test.class.getClassLoader().getResourceAsStream(
  14. "person.xml");
  15. // List<Student> stus = PullXMLTools.parseXML(is,"utf-8");
  16. // List<Student> stus = DomXMLTools.parseXML(is);
  17. List<Student> stus = SaxXMLTools.parseXML(is);
  18. for (Student student : stus) {
  19. System.out.println(student.toString());
  20. }
  21. }
  22.  
  23. }

猜你在找的XML相关文章