Android 使用pull,sax解析xml
Posted R丶decade
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 使用pull,sax解析xml相关的知识,希望对你有一定的参考价值。
pull解析xml文件
1.获得XmlpullParser类的引用
这里有两种方法
//解析器工厂 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); XmlPullParser pullParser=factory.newPullParser();
//直接获得实例
XmlPullParser pullParser= Xml.newPullParser();
2.设置解析内容
通过setInput方法设置解析内容 重载写的很清楚 把xml文件读取到Reader 或 InputStream中 注意 InputStream需要指定编码
pullParser.setInput(getAssets().open("student.xml"),"utf-8");
getAssets().open("student.xml")返回一个字节流InputStream 所以需要指定编码格式
3.获取当前的事件类型 开始解析
START_DOCUMENT 开始读取文档
END_DOCUMENT 结束读取文档
START_TAG 开始读取标签
END_TAG 结束读取标签
xml数据
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <persons>
3 <person id="1">
4 <name>张三</name>
5 <age>23</age>
6 </person>
7 <person id="2">
8 <name>李四</name>
9 <age>23</age>
10 </person>
11 </persons>
pull解析核心代码
1 try {
2 //解析器工厂
3 XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
4 //创建解析器
5 XmlPullParser pullParser=factory.newPullParser();
6 //直接创建解析器 7 //pullParser= Xml.newPullParser();
8 //设置解析内容
9 //getAssets().open("student.xml")返回一个字节流InputStream 所以需要指定编码格式
10 pullParser.setInput(getAssets().open("student.xml"),"utf-8");
11 //开始解析
12 //获取当前解析的标签
13 //获取当前事件类型:开始读取文档,开始读取标签,结束标签,结束读取文档 类似一个状态
14 int type=pullParser.getEventType();
15 while (type!=XmlPullParser.END_DOCUMENT){
16 switch (type){
17 //开始读取文档
18 case XmlPullParser.START_DOCUMENT:
19 break;
20 //开始读取标签
21 case XmlPullParser.START_TAG:
22 String tag=pullParser.getName();//获取节点名
23 if(tag.equals("person")){
24 person=new Person();
25 //获取节点属性
26 String id=pullParser.getAttributeValue("","id");
27 if (TextUtils.isEmpty(id)) continue;
28 person.setId(Integer.parseInt(id));
29 }else if(tag.equals("name")){
30 //获取下一个文本
31 String name=pullParser.nextText();
32 if (TextUtils.isEmpty(name)) continue;
33 person.setName(name);
34 }else if(tag.equals("age")){
35 String age=pullParser.nextText();
36 if (TextUtils.isEmpty(age)) continue;
37 person.setAge(Integer.parseInt(age));
38 }
39 break;
40 //结束读取标签
41 case XmlPullParser.END_TAG:
42 tag=pullParser.getName();
43 //当一个person 读取完成之后 添加到list
44 if(tag.equals("person")){
45 persons.add(person);
46 }
47 break;
48 //结束读取文档
49 case XmlPullParser.END_DOCUMENT:
50 break;
51 }
52 //读取下一个事件
53 type=pullParser.next();
54 }
55 } catch (XmlPullParserException e) {
56 e.printStackTrace();
57 } catch (IOException e) {
58 e.printStackTrace();
59 }
这里提一下getAttributeValue()方法 获取节点属性 有两个参第一个参数代表的是命名空间 什么xml是里的命名空间呢 一般xml文件根元素附加都会有xmlns 这就定义命名空间的
给属性添加命名空间后 就表示是那个命名空间的属性 类似包名 不过不常用
SAX解析xml数据
sax对文档进行顺序扫描 当扫描到文档开始结束,元素开始结束,标签开始结束都会触发事件
sax的使用和pull差不多 个人喜欢用sax多一点,sax采用的事件驱动
sax是通过重写方法来实现,符合条件就会触发回调 这些方法都是定义在ContentHandler接口中,android为我们提供了一个帮助类DefaultHandler,只需要继承这个类,重写方法就ok
核心代码
1 try { 2 //创建SAX解析器 3 SAXParserFactory factory=SAXParserFactory.newInstance(); 4 SAXParser parser= factory.newSAXParser(); 5 //自定一个Handler解析器 6 PersonHandler handler=new PersonHandler(); 7 //解析器对xml进行解析 8 parser.parse(getAssets().open("student.xml"),handler); 9 for(Person p:handler.getPersonList()){ 10 Log.e("XmlSAXParser",p.getName()+"====="+p.getAge()+"=========="+p.getId()); 11 } 12 } catch (ParserConfigurationException e) { 13 e.printStackTrace(); 14 } catch (SAXException e) { 15 e.printStackTrace(); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 }
解析器代码
1 public class PersonHandler extends DefaultHandler {
2 //保存数据
3 private List<Person> personList;
4 private Person person;
5 //节点名称 当前解析的元素名
6 private String tag;
7
8 /**
9 * 处理xml文件中读到到文本内容
10 * @param ch 字符串内容
11 * @param start 起始位置
12 * @param length 长度
13 * @throws SAXException
14 */
15 @Override
16 public void characters(char[] ch, int start, int length) throws SAXException {
17 super.characters(ch, start, length);
18 //创建成字符串
19 String text=new String(ch,start,length).trim();
20 //字符串不能为空,既不读取空的文本节点,如换行
21 if(TextUtils.isEmpty(text)) return;
22 //当节点名称等于name时赋值
23 if("name".equals(tag)){
24 person.setName(text);
25 }else if("age".equals(tag)){
26 person.setAge(Integer.parseInt(text));
27 }
28 }
29
30 /**
31 *
32 * @param uri 命名空间 没啥用
33 * @param localName 前缀标签名 没啥用
34 * @param qName 节点名字
35 * @param attributes 属性集合
36 * @throws SAXException
37 */
38 @Override//qName attributes
39 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
40 super.startElement(uri, localName, qName, attributes);
41 tag=qName;
42 //为什么创建集合 和对象 请看上面的xml 仔细分析
43 if("persons".equals(qName)){
44 //数据存储的集合
45 personList=new ArrayList<>();
46 }else if("person".equals(qName)){
47 person=new Person();
48 String id=attributes.getValue("id");
49 if (!TextUtils.isEmpty(id)){
50 person.setId(Integer.parseInt(id));
51 }
52 }
53 }
54
55 @Override
56 public void endElement(String uri, String localName, String qName) throws SAXException {
57 super.endElement(uri, localName, qName);
58 if("person".equals(qName)){
59 personList.add(person);
60 }
61 }
62
63 }
还有startElement startDocument endDocument等方法
过几天会整理一个xml和listview的简单使用的Demo
以上是关于Android 使用pull,sax解析xml的主要内容,如果未能解决你的问题,请参考以下文章