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() + "]");
			}
		}
	}

}





示例代码