Android基础——XML数据的三种解析方式
本篇文章包含以下内容:
- XML数据的Dom解析
- XML数据的Sax解析
- XML数据的Pull解析
- Activity中使用三种解析
- Sax解析与Pull解析区别
三种解析方式的步骤:
- 在Assets文件夹中模拟创建XML数据
- 创建对应XML的Bean对象
- 开始解析
XML数据的Dom解析
DOM解析XML文件时,会将XML文件的所有内容读取到内存中(内存的消耗比较大),然后允许您使用DOM API遍历XML树、检索所需的数据
一、在Assets文件夹中模拟创建XML文件
<students> <student> <name sex="man">小明</name> <nickName>明明</nickName> </student> <student> <name sex="woman">小红</name> <nickName>红红</nickName> </student> <student> <name sex="man">小亮</name> <nickName>亮亮</nickName> </student></students>
二、创建对应XML的Bean对象
public class Student { private String name; private String sex; private String nickName; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", nickName='" + nickName + '\'' + '}'; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
三、Dom解析
public List<Student> dom2xml(InputStream is) throws Exception { List<Student> list = new ArrayList<>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(is); NodeList studentList = document.getElementsByTagName("student"); for (int i = 0; i < studentList.getLength(); i++) { Node node_student = studentList.item(i); NodeList childNodes = node_student.getChildNodes(); Student student = new Student(); for (int j = 0; j < childNodes.getLength(); j++) { Node childNode = childNodes.item(j); if ("name".equals(childNode.getNodeName())) { String name = childNode.getTextContent(); student.setName(name); NamedNodeMap nnm = childNode.getAttributes(); Node n = nnm.item(0); student.setSex(n.getTextContent()); } else if ("nickName".equals(childNode.getNodeName())) { String nickName = childNode.getTextContent(); student.setNickName(nickName); } } list.add(student); } return list;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
XML数据的Sax解析
SAX是一个解析速度快并且占用内存少的xml解析器,SAX解析XML文件采用的是事件驱动,它并不需要解析完整个文档,而是按内容顺序解析文档的过程
由于前面一和二的步骤是一样的,这里就省略了
三、Sax解析
public List<Student> sax2xml(InputStream is) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); MyHandler handler = new MyHandler(); sp.parse(is, handler); return handler.getList();}public class MyHandler extends DefaultHandler { private List<Student> list; private Student student; private String tempString; /** * 解析到文档开始调用,一般做初始化操作 * * @throws SAXException */ @Override public void startDocument() throws SAXException { list = new ArrayList<>(); super.startDocument(); } /** * 解析到文档末尾调用,一般做回收操作 * * @throws SAXException */ @Override public void endDocument() throws SAXException { super.endDocument(); } /** * 每读到一个元素就调用该方法 * * @param uri * @param localName * @param qName * @param attributes * @throws SAXException */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("student".equals(qName)) { student = new Student(); } else if ("name".equals(qName)) { String sex = attributes.getValue("sex"); student.setSex(sex); } super.startElement(uri, localName, qName, attributes); } /** * 读到元素的结尾调用 * * @param uri * @param localName * @param qName * @throws SAXException */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("student".equals(qName)) { list.add(student); } if ("name".equals(qName)) { student.setName(tempString); } else if ("nickName".equals(qName)) { student.setNickName(qName); } super.endElement(uri, localName, qName); } /** * 读到属性内容调用 * * @param ch * @param start * @param length * @throws SAXException */ @Override public void characters(char[] ch, int start, int length) throws SAXException { tempString = new String(ch, start, length); super.characters(ch, start, length); } /** * 获取该List * * @return */ public List<Student> getList() { return list; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
XML数据的Pull解析
Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,可以使用一个switch对感兴趣的事件进行处理
三、Pull解析
public List<Student> pull2xml(InputStream is) throws Exception { List<Student> list = null; Student student = null; XmlPullParser parser = Xml.newPullParser(); parser.setInput(is, "utf-8"); int type = parser.getEventType(); while (type != XmlPullParser.END_DOCUMENT) { switch (type) { case XmlPullParser.START_TAG: if ("students".equals(parser.getName())) { list = new ArrayList<>(); } else if ("student".equals(parser.getName())) { student = new Student(); } else if ("name".equals(parser.getName())) { String sex = parser.getAttributeValue(null,"sex"); student.setSex(sex); String name = parser.nextText(); student.setName(name); } else if ("nickName".equals(parser.getName())) { String nickName = parser.nextText(); student.setNickName(nickName); } break; case XmlPullParser.END_TAG: if ("student".equals(parser.getName())) { list.add(student); } break; } type = parser.next(); } return list;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
Activity中使用三种解析
public class XmlActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv; private Button bt_dom, bt_sax, bt_pull; private XmlUtils xmlUtils; private List<Student> students; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_xml); tv = (TextView) findViewById(R.id.tv); bt_dom = (Button) findViewById(R.id.bt_dom); bt_sax = (Button) findViewById(R.id.bt_sax); bt_pull = (Button) findViewById(R.id.bt_pull); bt_dom.setOnClickListener(this); bt_sax.setOnClickListener(this); bt_pull.setOnClickListener(this); xmlUtils = new XmlUtils(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_dom: try { students = xmlUtils.dom2xml(getResources().getAssets().open("student.xml")); tv.setText(students.toString()); } catch (Exception e) { e.printStackTrace(); } break; case R.id.bt_sax: try { students = xmlUtils.sax2xml(getResources().getAssets().open("student.xml")); tv.setText(students.toString()); } catch (Exception e) { e.printStackTrace(); } break; case R.id.bt_pull: try { students = xmlUtils.pull2xml(getResources().getAssets().open("student.xml")); tv.setText(students.toString()); } catch (Exception e) { e.printStackTrace(); } break; } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
三种解析方式的效果图是一样的
Sax解析与Pull解析区别
SAX和Pull的区别:SAX解析器的工作方式是自动将事件推入事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。