一、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>
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 举报,一经查实,本站将立刻删除。