-------------------------------------SAX解析xml----------------------------------

》Sax定义

SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于android等移动设备

SAX全称是Simple API for Xml,既是指一种接口,也是一个软件包

作为接口,sax是事件驱动型xml解析的一个标准接口

》Sax特点

1. 解析效率高,占用内存少

2.可以随时停止解析

3.不能载入整个文档到内存

4.不能写入xml

5.SAX解析xml文件采用的是事件驱动

---sax并不需要解析完 整个文档,在按内容顺序解析文档的过程中,sax会判断当前读到的字符是否合法xml语法中的某部分,如果符合就会触发事件

》Sax工作原理

Sax的工作原理简单的说,就是对文档进行顺序扫描,扫描到文档(document)开始与结束,扫描到元素(element)开始、结束等地方时调用事件处理

处理函数做相应动作,然后继续扫描,直到文档结束。

》Sax解析文档过程

1.继承DefaultHandler  ,并实现方法

2.创建SAX解析器工厂

3.获得解析器

4.获得输入流

5.使用输入流,和实现接口作参数,调用解析器的解析方法进行解析

》defaultHandler 接口是实现contentHandler接口

ContentHandler接口中的常用方法

>startDocument()

当遇到文档开头的时候,调用这个方法,可以在其中做一些与准备工作

>endDocument()

当文档结束的时候,调用这个方法,可以在其中做一些善后工作

>startElement(String namespaceURL, String localName, String qName, Attributes atts)

当读到一个开始标签的时候,会触发这个方法。namespaceURL就是命名空间,localName是不带命名空间前缀的标签名,

qName是待命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。

>endElement(String uri, String localName, String name)

当遇到结束标签的时候,调用这个方法

>characters(char[] ch, int start, int length)

这个方法用来处理在xml文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,

使用new String(ch, start, length)就可以获取内容

》SAX解析实例

-------------1.在src下创建xml 文件,并结合成实体类Userinfo.java-------------

<?xml version="1.0" encoding="UTF-8"?>
<admins>
<admin id="1">
<name>阿龙</name>
<age>23</age>
<sex>男</sex>
<email>along@qq.com</email>
</admin>
</admins>

----------Userinfo.java----

String name;
int age;
String sex;
String email;
String id;

。。。  生成get、set方法

--------------------2.创建XmlPaser继承defaultHandler----------------------

public class XmlPaser extends DefaultHandler{

//创建user对象为把查到的内容放到里面

Userinfo user;
public Userinfo getUser() {
return user;
}
public void setUser(Userinfo user) {
this.user = user;
}

//定义标签变量

String tagName = null;

//开始文档处理些准备工作

public void startDocument() throws SAXException {

user = new Userinfo();
super.startDocument();
}

//读到第一个标签触发

public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tagName = localName;
if("admin".equals(tagName)){
user.setId(attributes.getValue(0));
System.out.println("id:  "+attributes.getValue(0));
}
}

//读取文本内容

public void characters(char[] ch, int start, int length)
throws SAXException {
if(tagName!=null){
if("name".equals(tagName)){
String str = new String(ch,start,length);
user.setName(str);

System.out.println("name:  "+str);
}else if("age".equals(tagName)){
String str = new String(ch,start,length);
user.setAge(Integer.parseInt(str));
System.out.println("age:   "+str);
}else if("sex".equals(tagName)){
String str = new String(ch,start,length);
user.setSex(str);
System.out.println("sex:  "+str);
}else if("email".equals(tagName)){
String str = new String(ch,start,length);
user.setEmail(str);
System.out.println("email:  "+str);

}
}
}

//遇到结束标签

public void endElement(String uri, String localName, String qName)
throws SAXException {

tagName=null;

}

//文档读完

public void endDocument() throws SAXException {

super.endDocument();
}

}

----------------布局文件main省略-----------

----------------------3.-类SAXActivity继承Activity----------------

Button btnOk;

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

btnOk = (Button)this.findViewById(R.id.button1);
        btnOk.setOnClickListener(new OnClickListener() {

public void onClick(View v){

//创建解析工厂和解析器

SAXParserFactory spf = SAXParserFactory.newInstance();

try{

SAXParser sp = spf.newSAXParser();

//解析

XmlPaser xp = new XmlPaser();

InputStream is = this.getClass().getClassLoader().getResourceAsStream("user.xml");

sp.parse(is,xp);

//获得读取到的内容

Userinfo user = xp.getUser();

//在页面显示

.................

}

}

});

}

---------------------------------------Dom解析Xml--------------------------------------------

》DOM简介

dom全称Document Object Model ,为xml文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个主流内存的树结构,

然后代码就可以使用dom接口来操作这个树结构

》DOM的特点

>优点

1.整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能

2.通过树形结构存取xml文档

3.可以在树的某个节点上向前或向后移动

>缺点

1.将整个文档调入内存(包括无用的节点),浪费时间和空间

>适用场合

一旦解析了文档还需多次访问这些数据;硬件资源充足(内存,cpu)

》DOM解析步骤

1.创建解析器工厂

2.获得解析器工厂

3.接受一个xml文档作为输入参数名,并得到一个xml的文档对象(Document)

4.操作文档对象

》解析实例:

-----------------------1.创建要解析的xml文件、和实体类(Person)---------------------------

<?xml version="1.0" encoding="utf-8"?>
<users>
<user id="1">
<name>Tom</name>
<age>19</age>
</user>
<user id="2">
<name>Jaary</name>
<age>18</age>
</user>
</users>

实体类 略

-----------------------2. Dom解析(DomService.java)-----------------------------------

public List<Person> getPersons(InputStream input) throws Throwable{

//获得解析器工厂

DocumentBuilderFactory    factory = DocumentBuilderFactory.newInstance();

//获得解析器

DocumentBuilder builder = factory.newDocumentBuilder();

//进行解析

Document  doc = builder.parse(input);

List<Person> personlist = new new ArrayList<Person>();

//获得所有叫user的节点

NodeList  list = doc.getElementsByTagName(user);

String id="";
String name="";
String age="";
for(int i=0;i<list.getLength();i++){
//取得第i个user节点
Element node=(Element)list.item(i);
Person p=new Person();
//获取id属性
id=node.getAttribute("id");
//获得user节点下的子节点列表
NodeList userList=node.getChildNodes();
for(int j=0;j<userList.getLength();j++){
//判断是否是元素节点,name和age属于元素节点
if(userList.item(j).getNodeType()==Node.ELEMENT_NODE){

Element childNode=(Element)userList.item(j);
if("name".equals(childNode.getNodeName())){
name=childNode.getFirstChild().getNodeValue();
}
else if("age".equals(childNode.getNodeName())){
age=childNode.getFirstChild().getNodeValue();
}
p.setName(name);
p.setAge(age);
p.setId(Integer.parseInt(id));
}

}

personList.add(p);
}
return personList;

}

-------------------------3.Activity01继承Activity类----------------------------------------------------

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        InputStream is=this.getClass().getClassLoader().getResourceAsStream("test.xml");
        DomService dom=new DomService();
        
        try {
List<Person> ps=dom.getPersons(is);
for(Person p:ps){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
} catch (Exception e) {

e.printStackTrace();
}
    }

--------------------------------------pull解析-----------------------------

》pull解析器简介

1.pull解析器是android内置的解析器,解析原理与sax类似

2.pull它提供了类似的事件。

如:开始元素和结束元素事件,使用parse.next()可以进入下一个元素并触发相应的事件,事件将作为数值代码被发送

因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法获取下一个Text类型节点的值

》pull与sax的不同之处

1.pull读取xml文件后触发相应的事件调用方法返回的是数字。

2.pull可以在程序中控制,想解析到哪里就可以停止到哪里

3.Android中更推荐使用pull解析

》pull解析步骤

1.创建解析器对象

XmlPullParser paser = Xml.newPullParser();

2.进行解析

paser.setInput(input,"utf-8");

3.产生第一个解析事件

int eventType = paser.getEventType();

4.可以使用循环判断是否继续解析

while(eventType!=XmlPullParser.END_DOCUMENT){}

》解析实例

-------------------1。创建xml.及实例对象(Person.java)----------------略

--------------------2.pull解析(PullService .java)----------------------

List<Person> getAlPerson(InputStream is) throws XmlPullParserException, IOException{

List<Person> persons=null;
Person p=null;
XmlPullParser parser=Xml.newPullParser();
parser.setInput(is,"utf-8");
//获得事件类型
int type=parser.getEventType();
while(type!=XmlPullParser.END_DOCUMENT){

switch(type){

case XmlPullParser.START_DOCUMENT://文档开始
persons=new ArrayList<Person>();
break;
case XmlPullParser.START_TAG://元素开始
if(parser.getName().equals("user")){

p=new Person();
String id=parser.getAttributeValue(0);
p.setId(Integer.parseInt(id));
}
else if(parser.getName().equals("name")){
if(p!=null){

String name=parser.nextText();
p.setName(name);
}
}
else if(parser.getName().equals("age")){

String age=parser.nextText();
p.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if("user".equals(parser.getName())){

persons.add(p);
p=null;
}
break;

}
type=parser.next();
}
return persons;
}
}

------------------------------------Activity类-----------------------------------

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        InputStream is=this.getClass().getClassLoader().getResourceAsStream("test.xml");
        PullService pps=new PullService();
        
        try {
List<Person> ps=pps.getPersons(is);
for(Person p:ps){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    }

SAX、DOM、PULL的比较

SAX、DOM、PULL各有自己的特点,具体操作XML的时候该如何选择呢?

1.内存占用

这是一个根本性问题。由于Android手机性能相对于现在的应用操作还是有限的,程序对内存的占用直接影响到了解析XML的速度。在这点上,SAX、Pull以它们比DOM占用更少的内存的解析方式,更适合于Android手机开发。

2.编程方式

SAX采用事件驱动,在相应事件触发的时候,会调用用户编写好的方法。也就是说,每解析一类XML,就要编写一个新的适合该类XML的处理类。这显然不是一个好的解决办法,尽管其在解析速度上是那么优秀。而这点,DOM因为是W3C的规范。所以被更多程序员所知道和使用。所以在开发过程中,没有太大困难。Pull虽然属于一个小众的,甚至是不为人知的解析器,但是通过上面对其介绍和示例,我们应该能看出它的简洁性。

3.访问与修改

由于采用的是流式解析,这就说明它们不能像DOM那样随机访问,XML的其中任意一个节点。并且,SAX并没有提供对文档中加节点的API,更没有删除,修改文档内容的方法。

4.访问方式

这是产生它们解析快慢的根本原因。如果把SAX和Pull比喻成一目十行,很快但是是走马观花的阅读方式的话,那么DOM就是逐字逐句的阅读,很慢,但是是过目不忘。这里还要需要注意的是,SAX,Pull解析的方式是同步的,即解析器读到哪里,就对哪里进行处理。而DOM是已经将文件解析好后,供用户提取XML中感兴趣的信息。

总结:

出于对内存占用的考虑,推荐使用SAX或者Pull来工作。可是根据它们工作的原理:如果只是需要XML最后的几个节点的相关信息,或者出现反复检索XML文件的情况。那么基本上三者在性能上就没有什么差异,反而在这时,SAX的处理类会使程序显得比其他的实现方式显得臃肿。所以,想做一个高性能的Android软件,还是要多分析,选择合适的工具,才能发挥它的作用。

Java sax、dom、pull解析xml的更多相关文章

  1. Android系列--DOM、SAX、Pull解析XML

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  2. Android SAX、DOM、Pull解析xml文件剖析与案例讲解

    XML介绍 XML(Extensible Markup Language) 即可扩展标记语言,与HTML一样,都是SGML(Standard Generalized Markup Language,标 ...

  3. Android学习笔记_7_使用 sax 或者 dom 或者 pull 解析XML文件

    一.Pull解析介绍: Android上使用SAX和DOM方式解析XML的方法,并且对两种做了简单的比较,通过比较我们知道对在往往内存比较稀缺的移动设备上运行的Android系统来说,SAX是一种比较 ...

  4. Android之Pull解析XML

    一.Pull解析方法介绍 除了可以使用SAX和DOM解析XML文件,也可以使用Android内置的Pull解析器解析XML文件.Pull解析器的运行方式与SAX解析器相似.它也是事件触发的.Pull解 ...

  5. 使用PULL解析XML文件

    转载博文1:http://blog.csdn.net/wangkuifeng0118/article/details/7313241 XmlPull和Sax类似,是基于流(stream)操作文件,然后 ...

  6. 转:在java中使用dom4j解析xml

    JAVA 使用Dom4j 解析XML Java DOM4J Parser - Parse XML Document Dom4j下载及使用Dom4j读写XML简介 在java中使用dom4j解析xml ...

  7. 用DOM方式解析XML

    一.用DOM方式解析XML 此例子节点结构如下: 1.获取book节点属性 (1).如果不知道节点的属性,通过 NamedNodeMap attrs = book.getAttributes(); 来 ...

  8. PULL解析XML的运行机制详解

    PULL解析简单易上手,基本上看一遍,基本上就会解析啦,但总是感觉对PULL解析的运行机制不是很了解,就总结了以下事件驱动到底是怎么执行的.. PULL: Android内置了PULL解析器.PULL ...

  9. 用JAXP的dom方式解析XML文件

    用JAXP的dom方式解析XML文件,实现增删改查操作 dom方式解析XML原理 XML文件 <?xml version="1.0" encoding="UTF-8 ...

随机推荐

  1. 走进JavaScript——重拾函数

    创建函数 通过构造器的方式来创建函数,最后一个参数为函数体其他为形参 new Function('a','b','alert(a)') /* function anonymous(a,b) { ale ...

  2. 创建hbase-indexer出现 0 running

    新建hbase-indexer后通过hbase-indexer list-indexers发现SEP subscription ID: null并且0 running processes,如下: IN ...

  3. python脚本0b文件处理

    要处理的文件: 此处处理将00的数据干掉. 处理python脚本: dir_fd = open('abc.yuv','rb+') tmp_fd = open('tmp.yuv','wb+') whil ...

  4. arm 异常处理结构

    概念:正常的程序执行过程中发生暂时的停止称为异常,如果发现异常情况,将会进行异常处理 作用:快速响应用户的行为,提高cpu的响应能力 异常类型: 异常处理的三个步骤: 1.保护现场: 工作模式保存:C ...

  5. ubuntu 开发板ping通虚拟机挂载nfs服务器

    先.nfs服务配置1.设置开发板ip ,同一网段2.开发板上操作:ifconfig eth0 192.168.1.203.测试是否能够ping通:ping 192.168.1.194.测试开发板ip是 ...

  6. hibernate之实体@onetomany和@manytoone双向注解(转)

    下面是User类: @onetomany @Entity @Table(name="user") public class User implements Serializable ...

  7. PHP函数register_shutdown_function的用法

    register_shutdown_function这个函数是在PHP程序运行结束之前调用的,用这个函数可以做很多,比如调用运行发生致命错误中止的原因,或者调试程序的执行时间等. PHP终止的情况有哪 ...

  8. Entity Framework——配置文件设置

    可以使用配置文件或代码(EF6起)配置EF框架. 一.使用配置文件 安装Entity Framework自动生成的配置 当使用VS的NuGet自动安装Entity Framework(本文使用6.2. ...

  9. Django在form提交CSRF验证失败. 相应中断问题

    CSRF验证失败. 相应中断. 1).首先,我们可以先看一下出现问题的所在的原因. Your browser is accepting cookies. The view function passe ...

  10. hdu 1207 四柱汉诺塔

    递推,汉诺塔I的变形. 这题真心没想到正确解法,越想越迷糊.这题看了别人题解过得,以后还是自己多想想,脚步太快并非好事. 贴上分析:   分析:设F[n]为所求的最小步数,显然,当n=1时,F[n]= ...