微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XML文件解析

一、xml文件的三种解析方式

1.DOM

在Dom解析的过程中,是先把dom全部文件读入到内存中,然后使用dom的api遍历所有数据,检索想要的数据,这种方式显然是一种比较消耗内存的方式,对于像手机这样的移动设备来讲,内存是非常有限的,所以对于比较大的XML文件,不推荐使用这种方式,但是Dom也有它的优点,它比较直观,在一些方面比SAX方式比较简单。在xml文档比较小的情况下也可以考虑使用dom方式。

2.SAX

这种方式解析是一种基于事件驱动的api,有两个部分,解析器和事件处理器,解析器就是XMLReader接口,负责读取XML文档,和向事件处理器发送事件(也是事件源),事件处理器ContentHandler接口,负责对发送的事件响应和进行XML文档处理。

下面是ContentHandler接口的常用方法

public abstract void characters (char[] ch,int start,int length)

这个方法来接收字符块通知,解析器通过这个方法来报告字符数据块,解析器为了提高解析效率把读到的所有字符串放到一个字符数组(ch)中,作为参数传递给character的方法中,如果想获取本次事件中读取到的字符数据,需要使用start和length属性

public abstract void startDocument () 接收文档开始的通知

public abstract void endDocument () 接收文档结束的通知

public abstract void startElement (String uri,String localName,String qName,Attributes atts) 接收文档开始的标签

public abstract void endElement (String uri,String qName)接收文档结束的标签

在一般使用中为了简化开发,在org.xml.sax.helpers提供了一个DefaultHandler类,它实现了ContentHandler的方法,我们只需要继承DefaultHandler方法即可。

另外SAX解析器提供了一个工厂类:SAXParserFactory,SAX的解析类为SAXParser 可以调用它的parser方法进行解析。

3.PULL

在android系统中,很多资源文件中,很多都是xml格式,在android系统中解析这些xml的方式,是使用pul解析器进行解析的,它和sax解析一样(个人感觉要比sax简单点),也是采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法获取属性的值,也可调用它的nextText()获取本节点的值。

二、待解析的xml文件

<pre name="code" class="html"><?xml version="1.0" encoding="UTF-8"?>
<students>
   <student name="张三" age="20" sex="男">
       <introduction>张三是个乐观开朗的大男孩</introduction>
       <grade>大二</grade>
       <mclass>工业设计一班</mclass>
   </student>
   <student name="李四" age="23" sex="女">
       <introduction>李四爱唱歌</introduction>
       <grade>大四</grade>
       <mclass>计算机一班</mclass>
   </student>
   <student name="小米" age="23" sex="女">
       <introduction>小米爱吃大米</introduction>
       <grade>大四</grade>
       <mclass>美声一班</mclass>
   </student>
   <student name="森宿" age="22" sex="女">
       <introduction>森宿爱做衣服</introduction>
       <grade>大四</grade>
       <mclass>服装设计一班</mclass>
   </student>
</students>
 

三、将xml文件的数据抽象为实体类

package com.xmldemo.javabean;

import java.io.Serializable;

public class Student implements Serializable{

	private String name;
	private int age;
	private String sex;
	private String introduction;
	private String grade;
	private String mclass;
	
	
	public Student() {
		super();
	}


	public Student(String name,int age,String sex,String introduction,String grade,String mclass) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.introduction = introduction;
		this.grade = grade;
		this.mclass = mclass;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public int getAge() {
		return age;
	}


	public void setAge(int age) {
		this.age = age;
	}


	public String getSex() {
		return sex;
	}


	public void setSex(String sex) {
		this.sex = sex;
	}


	public String getIntroduction() {
		return introduction;
	}


	public void setIntroduction(String introduction) {
		this.introduction = introduction;
	}


	public String getGrade() {
		return grade;
	}


	public void setGrade(String grade) {
		this.grade = grade;
	}


	public String getMclass() {
		return mclass;
	}


	public void setMclass(String mclass) {
		this.mclass = mclass;
	}
	
	
}


四、解析详解

1.DOM解析实例

public static List<Student> Domread(String fileName) {
		List<Student> result=new ArrayList<Student>();
		File dir=new File(Environment.getExternalStorageDirectory()+"/dom");
		if(!dir.exists())
			dir.mkdirs();
		File file=new File(dir,fileName);
		//获取DOM工厂对象
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		try {
			//获取DocumentBuilder对象
			DocumentBuilder builder=factory.newDocumentBuilder();
			//获取文档对象
			Document document=builder.parse(file);
			//获取文档对象根目录
			Element root=document.getDocumentElement();
			//获取根目录下student节点
			NodeList nodeList=root.getElementsByTagName("student");
			for (int i = 0; i < nodeList.getLength(); i++) {
				Student student=new Student();
				//获取students下的子节点
				Element element=(Element) nodeList.item(i);
				//获取student里的属性值
				student.setName(element.getAttribute("name"));
				student.setAge(Integer.parseInt(element.getAttribute("age")));
				student.setSex(element.getAttribute("sex"));

				//获取student下的子节点introduction
				Element introduction=(Element) element.getElementsByTagName("introduction").item(0);
				//获取introduction节点的内容
				student.setIntroduction(introduction.getTextContent());

				//获取student下的子节点grade
				Element grade=(Element) element.getElementsByTagName("grade").item(0);
				//获取grade节点的内容
				student.setGrade(grade.getTextContent());

				//获取student下的子节点mclass
				Element mclass=(Element) element.getElementsByTagName("mclass").item(0);
				//获取mclass节点的内容
				student.setMclass(mclass.getTextContent());

				/*以下方法亦可
				//获取student下的子节点introduction
				Element introduction=(Element) element.getElementsByTagName("introduction").item(0);
				//获取introduction节点的内容
				student.setIntroduction(introduction.getFirstChild().getNodeValue());

				//获取student下的子节点grade
				Element grade=(Element) element.getElementsByTagName("grade").item(0);
				//获取grade节点的内容
				student.setGrade(grade.getFirstChild().getNodeValue());

				//获取student下的子节点mclass
				Element mclass=(Element) element.getElementsByTagName("mclass").item(0);
				//获取mclass节点的内容
				student.setMclass(mclass.getFirstChild().getNodeValue());*/

				result.add(student);
			}
		} catch (Exception e) {
		}
		return result;
	}





2.SAX解析实例

(1)实例化事件处理器,继承自DefaultHandler

package com.xmldemo.custom;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.R.integer;

import com.xmldemo.javabean.Student;

public class StudentHandler extends DefaultHandler {

	//解析的student对象存储到list集合中
	private List<Student> students;
	//解析当前的student对象
	public Student student;
	//声明标签名称
	public String tagName;
	//获取解析所有的student对象
	public List<Student> getStudents() {
		return students;
	}
	
	/**
	 * 文档开始触发的事件
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		students=new ArrayList<Student>();
	}
	
	/**
	 * 读到元素标签是开始执行
	 */
	@Override
	public void startElement(String uri,Attributes attributes) throws SAXException {
		super.startElement(uri,localName,qName,attributes);
		//判断解析的标签是否是student,只有标签为student时才需要做读取属性操作,其他标签只需把标签名存进tagName
		//localName和qName的值一样
		if(localName.equals("student")){
			student=new Student();
			//读取student属性值
			student.setName(attributes.getValue("name"));
			student.setAge(Integer.parseInt(attributes.getValue("age")));
			student.setSex(attributes.getValue("sex"));
			//currentPerson.setId(Integer.parseInt(attributes.getValue(0)));
		}
		this.tagName=localName;
	}
	
	/**
	 * 读取文本内容时执行
	 */
	@Override
	public void characters(char[] ch,int length)
			throws SAXException {
		super.characters(ch,start,length);
		//首先判断tagName是否为空
		if(tagName!=null){
			String data=new String(ch,length);
			//判断标签是否为空
			if(tagName.equals("introduction")){//判断标签是否是introduction
				student.setIntroduction(data);
			}else if(tagName.equals("grade")){//判断标签是否是grade
				student.setGrade(data);
			}else if(tagName.equals("mclass")){//判断标签是否是mclass
				student.setMclass(data);
			}
		}
	}
	
	/**
	 * 元素标签结束时执行
	 */
	@Override
	public void endElement(String uri,String qName)
			throws SAXException {
		super.endElement(uri,qName);
		//当student标签结束的时候把students对象存储到集合中
		if(localName.equals("student")){
			students.add(student);
			student=null;
		}
		this.tagName=null;
	}
	
	/**
	 * 文档结束时执行
	 */
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
	}
	
}

(2)通过SAXParserFactory等获得事件源XMLReader,并连接到时间处理类DefaultHandler

<span style="font-size:18px;">public static List<Student> SaxRead(Context context,String fileName) {
		List<Student> result=new ArrayList<Student>();
		try {
			//获取输入流
			InputStream inputStream=context.getResources().getAssets().open(fileName);
			//获取sax解析器
			SAXParserFactory factory=SAXParserFactory.newInstance();
			SAXParser parser=factory.newSAXParser();
			StudentHandler studentHandler=new StudentHandler();
			//获取事件源
			XMLReader xmlReader=parser.getXMLReader();
			//为事件源设置内容处理器
			xmlReader.setContentHandler(studentHandler);
			xmlReader.parse(new InputSource(inputStream));
			result=studentHandler.getStudents();
			//以下方式也可解析
//			parser.parse(inputStream,studentHandler);
//			result=studentHandler.getStudents();
		} catch (Exception e) {
			// Todo Auto-generated catch block
			e.printstacktrace();
		}
		return result;
	}</span>


3.PULL解析实例

public static List<Student> PullRead(Context context,String fileName) {
	List<Student> students=null;
	Student student=null;
	try {
		//获得文件输入流
		InputStream inputStream=context.getResources().getAssets().open(fileName);

		// 利用ANDROID提供的API快速获得pull解析器  
		XmlPullParser pullParser = Xml.newPullParser();  
		// 设置需要解析的XML数据,此时eventtype为 初始值START_DOCUMENT
		pullParser.setInput(inputStream,"UTF-8");  
		// 取得事件  
		int event = pullParser.getEventType();  
		// 若为解析到末尾  
		while (event != XmlPullParser.END_DOCUMENT) // 文档结束  
		{
			String nodeName = pullParser.getName();  
			switch (event)  
			{  
			case XmlPullParser.START_DOCUMENT: // 文档开始  
				students=new ArrayList<Student>();  
				break;  
			case XmlPullParser.START_TAG: // 标签开始  
				if ("student".equals(nodeName))  
				{  
					student = new Student(); 
					String name = pullParser.getAttributeValue(0);
					student.setName(name);
					String age = pullParser.getAttributeValue(1);
					student.setAge(Integer.parseInt(age));
					String sex = pullParser.getAttributeValue(2);
					student.setSex(sex);
				}  
				else if ("introduction".equals(nodeName))  
				{  
					/*If current event is START_TAG then if next element is 
						TEXT then element content is returned or if next event is 
						END_TAG then empty string is returned*/
					String introduction = pullParser.nextText();  
					student.setIntroduction(introduction);  
				}  
				else if ("grade".equals(nodeName))  
				{  
					String grade = pullParser.nextText();  
					student.setGrade(grade);  
				}  
				else if ("mclass".equals(nodeName))  
				{  
					String mclass = pullParser.nextText();  
					student.setMclass(mclass);
				} 
				break;  
			case XmlPullParser.END_TAG: // 标签结束  
				if ("student".equals(nodeName))  
				{  
					students.add(student);  
					student = null;  
				}  
				break;  
			default:
				break;
			} 
			event = pullParser.next(); // 下一个标签  
		} 
	} catch (Exception e) {
		// Todo Auto-generated catch block
		e.printstacktrace();
	}

	return students;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。