android一共提供了三种XMl解析的方式,分别为:SAX解析,Pull解析,DOM解析。
第一种:SAX解析:
xml解析,对文档进行顺序扫描,当扫描到document开始,元素的开始与结束,文档结束等地方通知相关处理事件处理函数,处理完函数之后继续进行扫描直到文档结束
实现步骤:通过SAXParserFactory得到一个SAXParser解析器,将文件流和处理类传递给SAXParser进行xml解析
示例代码如下:
首先xml格式如下:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1">
<name>张三</name>
<age>12</age>
</student>
<student id="2"><name>李四</name><age>13</age></student>
<student id="3">
<name>王某某</name>
<age>14</age>
</student>
<student id="4">
<name>红果果</name>
<age>13</age>
</student>
</students>
实体类Student如下:
public class Student {
private String id;
private String name;
private String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
SAX解析类:
public class SAXParser {
public void getStudentsFromXMl(InputStream stream) throws SAXException, IOException, ParserConfigurationException {
SAXParserFactory factory=SAXParserFactory.newInstance();//创建SAX解析工厂
javax.xml.parsers.SAXParser parser=factory.newSAXParser();//创建SAX解析器
SAXHandler handler=new SAXHandler();//创建处理函数
parser.parse(stream, handler);//开始解析
handler.getStudents();
}
}
SAX处理类
public class SAXHandler extends DefaultHandler {
private List<Student> students;
private Student student;// 当前解析的student
private String tag;// 当前解析的标签
public void getStudents() {
if(students!=null){
for (int i = 0; i < students.size(); i++) {
Log.e("msg","student [id="+students.get(i).getId()+", name="+students.get(i).getName()+", age="+students.get(i).getAge()+"]");
}
}
}
@Override
public void startDocument() throws SAXException {
// 文档开始
// Log.e("hr", "1.startDocument 文档开始");
students = new ArrayList<Student>();
}
@Override
public void endDocument() throws SAXException {
// 文档结束
// Log.e("hr", "5.endDocument 文档结束");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 节点开始
// Log.e("hr", "2.标签开始");
tag = localName;
if (localName.equals("student")) {
student = new Student();
student.setId(attributes.getValue("id"));
// 或者可以通过属性下标获取 attributes.getValue(0)
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 节点结束
// Log.e("hr", "4.标签结束");
if (localName.equals("student")) {
students.add(student);
student = null;
}
tag = null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// Log.e("hr", "3.文本数据,如果标签存在换行也会进入该方法,但是data数据为null,记得做非空判断");
String data = new String(ch, start, length);
if (data != null&&tag!=null) {
if (tag.equals("name")) {
student.setName(data);
} else if (tag.equals("age")) {
student.setAge(data);
}
}
}
}
第二种方式Pull解析,它的解析原理和SAX是一样的,不同的是它需要我们自己根据产生事件做出相应的操作。pull解析小巧灵便,解析速度快,简单易用,是android推荐的方式
通过 Xml 获取一个XmlPullParser解析器,根据当前的eventType的不同类型进行相应的数据存取操作
具体代码如下:
public class PullParser {
private List<Student> students;
private Student student;
public void getStudentsFromXMl(InputStream stream) throws Exception{
XmlPullParser parser=Xml.newPullParser();//获取pull解析器
parser.setInput(stream, "utf-8");//设置输入流的编码方式
int eventType=parser.getEventType();//得到第一个事件类型
while (eventType!=XmlPullParser.END_DOCUMENT) {//直到文档结束一直循环处理
if(eventType==XmlPullParser.START_DOCUMENT){//文档开始
students=new ArrayList<Student>();
}else if(eventType==XmlPullParser.START_TAG){//标签开始
String tagName=parser.getName();//获取标签名称
if(tagName!=null){
if(tagName.equals("student")){
student=new Student();
student.setId(parser.getAttributeValue(0));
}else if(tagName.equals("name")){
student.setName(parser.nextText());
}else if(tagName.equals("age")){
student.setAge(parser.nextText());
}
}
}else if(eventType==XmlPullParser.END_TAG){//标签结束
String tagName=parser.getName();
if(tagName!=null&&tagName.equals("student")){
students.add(student);
student=null;
}
}
eventType=parser.next();
// Log.e("msg", "eventType="+eventType);
}
if(students!=null){
for (int i = 0; i < students.size(); i++) {
Log.e("msg","student [id="+students.get(i).getId()+", name="+students.get(i).getName()+", age="+students.get(i).getAge()+"]");
}
}
}
}
第三种方式:
Dom
解析,对象文档模型,将整个
Xml
文档载入内存中,把每个节点当做一个对象 不推荐使用
代码实现步骤:
通过DocumentBuilderFactory获取一个DocumentBuilder解析器得到一个Document 按照顺序解析这个
xml
树
具体代码如下:
public class DomParser {
private List<Student> students = null;
public void getStudentsFromXMl(InputStream stream) throws Exception {
students = new ArrayList<Student>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建DOM解析工厂
DocumentBuilder domBuilder = factory.newDocumentBuilder();// 创建Dom解析器
Document document = domBuilder.parse(stream);// 得到整个文档的对象模型
// NodeList nodeList=document.getChildNodes();//获取文档下面所有的子节点
NodeList nodeList = document.getElementsByTagName("student");// 获取文档下面所有的student标签
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
// if(node.getNodeType()==Node.ELEMENT_NODE){
Student student = new Student();
student.setId(node.getAttributes().item(0).getTextContent() + "");//获取属性值
NodeList childNodes = node.getChildNodes();//得到student标签下所有子节点
for (int j = 0; j < childNodes.getLength(); j++) {
Node childNode = childNodes.item(j);
if (node.getNodeType() == Node.ELEMENT_NODE) {
if (childNode.getNodeName().equals("name")) {
student.setName(childNode.getTextContent());//获取节点的文本值
} else if (childNode.getNodeName().equals("age")) {
student.setAge(childNode.getTextContent());
}
}
}
students.add(student);
// }
}
if (students != null) {
for (int i = 0; i < students.size(); i++) {
Log.e("msg", "student [id=" + students.get(i).getId()
+ ", name=" + students.get(i).getName() + ", age="
+ students.get(i).getAge() + "]");
}
}
}
public void getStudentsFromXMl2(InputStream stream) throws Exception {
students = new ArrayList<Student>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder domBuilder = factory.newDocumentBuilder();
Document document = domBuilder.parse(stream);
// NodeList nodeList=document.getChildNodes();//获取文档下面所有的子节点
NodeList nodeList = document.getElementsByTagName("student");// 获取文档下面所有的Student标签
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
Student student = new Student();
student.setId(element.getAttribute("id"));
NodeList childNodes = element.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) childNodes.item(j);
if (childElement.getNodeName().equals("name")) {
student.setName(childElement.getFirstChild()
.getNodeValue());// 得到name节点下第一个文本节点的值
} else if (childElement.getNodeName().equals("age")) {
student.setAge(childElement.getFirstChild()
.getNodeValue());
}
}
}
students.add(student);
}
if (students != null) {
for (int i = 0; i < students.size(); i++) {
Log.e("msg", "student [id=" + students.get(i).getId()
+ ", name=" + students.get(i).getName() + ", age="
+ students.get(i).getAge() + "]");
}
}
}
}
示例代码