Android 使用pull,sax解析xml

时间:2023-06-12 19:41:44

pull解析xml文件

1.获得XmlpullParser类的引用

    这里有两种方法

 //解析器工厂
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
XmlPullParser pullParser=factory.newPullParser(); //直接获得实例
XmlPullParser pullParser= Xml.newPullParser();

2.设置解析内容

Android 使用pull,sax解析xml

通过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数据

 <?xml version="1.0" encoding="UTF-8" ?>
<persons>
<person id="1">
<name>张三</name>
<age>23</age>
</person>
<person id="2">
<name>李四</name>
<age>23</age>
</person>
</persons>

pull解析核心代码

  try {
//解析器工厂
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
//创建解析器
XmlPullParser pullParser=factory.newPullParser();
//直接创建解析器 //pullParser= Xml.newPullParser();
//设置解析内容
//getAssets().open("student.xml")返回一个字节流InputStream 所以需要指定编码格式
pullParser.setInput(getAssets().open("student.xml"),"utf-8");
//开始解析
//获取当前解析的标签
//获取当前事件类型:开始读取文档,开始读取标签,结束标签,结束读取文档 类似一个状态
int type=pullParser.getEventType();
while (type!=XmlPullParser.END_DOCUMENT){
switch (type){
//开始读取文档
case XmlPullParser.START_DOCUMENT:
break;
//开始读取标签
case XmlPullParser.START_TAG:
String tag=pullParser.getName();//获取节点名
if(tag.equals("person")){
person=new Person();
//获取节点属性
String id=pullParser.getAttributeValue("","id");
if (TextUtils.isEmpty(id)) continue;
person.setId(Integer.parseInt(id));
}else if(tag.equals("name")){
//获取下一个文本
String name=pullParser.nextText();
if (TextUtils.isEmpty(name)) continue;
person.setName(name);
}else if(tag.equals("age")){
String age=pullParser.nextText();
if (TextUtils.isEmpty(age)) continue;
person.setAge(Integer.parseInt(age));
}
break;
//结束读取标签
case XmlPullParser.END_TAG:
tag=pullParser.getName();
//当一个person 读取完成之后 添加到list
if(tag.equals("person")){
persons.add(person);
}
break;
//结束读取文档
case XmlPullParser.END_DOCUMENT:
break;
}
//读取下一个事件
type=pullParser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

这里提一下getAttributeValue()方法 获取节点属性 有两个参第一个参数代表的是命名空间 什么xml是里的命名空间呢 一般xml文件根元素附加都会有xmlns 这就定义命名空间的

给属性添加命名空间后  就表示是那个命名空间的属性 类似包名  不过不常用 
Android 使用pull,sax解析xml
  SAX解析xml数据
  sax对文档进行顺序扫描 当扫描到
文档开始结束,元素开始结束,标签开始结束都会触发事件
  sax的使用和pull差不多 个人喜欢用sax多一点,sax采用的事件驱动
  sax是通过重写方法来实现,符合条件就会触发回调 这些方法都是定义在ContentHandler接口中,Android为我们提供了一个帮助类
DefaultHandler,只需要继承这个类,重写方法就ok
核心代码
  
 1        try {
//创建SAX解析器
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser= factory.newSAXParser();
//自定一个Handler解析器
PersonHandler handler=new PersonHandler();
//解析器对xml进行解析
parser.parse(getAssets().open("student.xml"),handler);
for(Person p:handler.getPersonList()){
Log.e("XmlSAXParser",p.getName()+"====="+p.getAge()+"=========="+p.getId());
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
解析器代码

 public class PersonHandler extends DefaultHandler {
//保存数据
private List<Person> personList;
private Person person;
//节点名称 当前解析的元素名
private String tag; /**
* 处理xml文件中读到到文本内容
* @param ch 字符串内容
* @param start 起始位置
* @param length 长度
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
//创建成字符串
String text=new String(ch,start,length).trim();
//字符串不能为空,既不读取空的文本节点,如换行
if(TextUtils.isEmpty(text)) return;
//当节点名称等于name时赋值
if("name".equals(tag)){
person.setName(text);
}else if("age".equals(tag)){
person.setAge(Integer.parseInt(text));
}
} /**
*
* @param uri 命名空间 没啥用
* @param localName 前缀标签名 没啥用
* @param qName 节点名字
* @param attributes 属性集合
* @throws SAXException
*/
@Override//qName attributes
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
tag=qName;
//为什么创建集合 和对象 请看上面的xml 仔细分析
if("persons".equals(qName)){
//数据存储的集合
personList=new ArrayList<>();
}else if("person".equals(qName)){
person=new Person();
String id=attributes.getValue("id");
if (!TextUtils.isEmpty(id)){
person.setId(Integer.parseInt(id));
}
}
} @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if("person".equals(qName)){
personList.add(person);
}
} }
还有startElement   startDocument endDocument等方法    

过几天会整理一个xml和listview的简单使用的Demo