android解析xml的类
㈠ Android灏哖PT镙煎纺镄刋ML鏁版嵁瑙f瀽锛屽苟瀹炵幇婕旂ず
涓銆俿imple-xml绗涓夋柟jar鍖呰В鏋恱ml镙煎纺鏁版嵁
simple-xml鏄涓涓獂ml鍜屽硅薄浜掕浆镎崭綔宸ュ叿鍖咃纴瀹樻柟缃戝潃涓猴细http://simple.sourceforge.net/锛宩ar鍖呭彲浠ュ埌瀹樼绣涓娄笅杞斤纴绗旇呬娇鐢ㄧ殑鏄鐩鍓嶆渶鏂扮増链镄刯ar鍖咃纴钖崭负simple-xml-2.7.1.jar锛涘帘璇濅笉澶氲翠简锛屼唬镰佹墠鏄链鐪熷疄闱犺氨镄勫姏璇併
涓嬮溃鏄鏁翠釜Demo宸ョ▼鏂囦欢鎴锲撅纴濡备笅锲撅细
璇Demo涓昏佹槸阃氲繃simple-xml瑙f瀽assets鐩褰曚腑镄刣ata.xml鏂囦欢鍐呭规暟鎹锛岀劧钖庢樉绀哄嚭𨱒ワ绂
1.data.xml鏂囦欢鍐呭瑰备笅锛
[html] view plain
<?xml version="1.0" encoding="utf-8"?>
<resources>
<?xml version="1.0" encoding="utf-8"?>
<dataContent>
<group>
<groupID>1</groupID>
<groupName>绗涓缁</groupName>
<member>
<name>寮犱笁</name>
<age>22</age>
</member>
<member>
<name>𨱒庡洓</name>
<age>24</age>
</member>
<member>
<name>娆ч槼闆</name>
<age>18</age>
</member>
</group>
<group>
<groupID>2</groupID>
<groupName>绗浜岀粍</groupName>
<member>
<name>鍙稿缅闱</name>
<age>19</age>
</member>
<member>
<name>鍙剁瑱</name>
<age>26</age>
</member>
<member>
<name>𨱒ㄩ</name>
<age>25</age>
</member>
</group>
<group>
<groupID>3</groupID>
<groupName>绗涓夌粍</groupName>
<member>
<name>鐜嬮緳</name>
<age>32</age>
</member>
<member>
<name>瑗块棬鑳灭敺</name>
<age>21</age>
</member>
<member>
<name>寮犻摤</name>
<age>45</age>
</member>
</group>
</dataContent>
</resources>
阃氲繃涓婇溃镄勬枃浠跺唴瀹癸纴鎴戜滑鐭ラ亾锛岃繖涓鏂囦欢鍐呭逛富瑕佹湁涓夌粍鏁版嵁锛屾疮缁勬暟鎹链変釜涓変釜鎴愬憳缁勶纴姣忎釜鎴愬憳缁勯兘链夊悕瀛楀拰骞撮缎杩欎袱涓瀛愬厓绱犮侱emo涓灏呜繖浜涜В鏋愬嚭𨱒ュ唴瀹归氲繃ExpandableListView鏄剧ず鍑烘潵銆
2.涓婚〉闱MainActivity浠g爜濡备笅锛
[java] view plain
package com.steven.android.simple.xml.activity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.simpleframework.xml.core.Persister;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.widget.ExpandableListView;
import com.steven.android.simple.xml.adapter.ExpandAdapter;
import com.steven.android.simple.xml.parse.DataParseResponse;
/**
* 鎻忚堪锛氢富椤甸溃
* @author stevenhu223
*
*/
public class MainActivity extends Activity {
private final String TAG = "MainActivity";
private ExpandableListView mExpandableListView;
private ExpandAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mExpandableListView = (ExpandableListView) findViewById(R.id.expanlist_content);
try {
matchAndParseData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* 鍖归厤銮峰彇鍜岃В鏋恱ml鏂囦欢鍐呭
* @throws Exception
*/
private void matchAndParseData() throws Exception {
InputStream inputStream = getResources().getAssets().open("data.xml");
String dataContent = convertStreamToString(inputStream);
String content = "";
//姝e垯琛ㄨ揪寮忓尮閰
Pattern DATA_PATTERN= Pattern.compile("[\\S\\s]*(<dataContent>[\\s\\S]*</dataContent>)[\\s\\S]*");
Matcher matcher = DATA_PATTERN.matcher(dataContent);
if (matcher.matches()) {
//銮峰彇鍖呭惈dataContent鍏幂礌镄勫唴瀹
content = matcher.group(1);
}
if (!TextUtils.isEmpty(content)) {
DataParseResponse dataResponse = parseToBean(DataParseResponse.class, content);
mAdapter = new ExpandAdapter(this, dataResponse.mGroupEntities);
mExpandableListView.setAdapter(mAdapter);
}
}
/**
* 灏唜ml鏂囦欢鍐呭硅В鏋愭垚瀹炰綋绫
㈡ android中用xmlpullparser解析xml文件,以及res/raw和assets的不同
XML:可扩展标记语言
读XML,XML文件的解析
三种解析XML的文件的方式
1.SAX事件驱动不是一次性加载到内存
2.DOM一次加载到内存,性能较差适合服务器端编程
3.XMLPULL适应嵌入式设备,占用内存较小API相对简单
OpenAPI
JSON:相对于XML格式,更节省空间。
1)大括号开始结束{}
2)内容部分每条数据以“,”分隔
3)每条数据由键值对构成,key必须是字符串“”
4)值可以是:String、double、int、long、boolean、
jsonObject、jsonArray
把要解析的XML文件放在assets目录下,这里解释下
res/raw和assets的相同点:
两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
读取文件资源:
1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
·InputStreamis=getResources().openRawResource(R.id.filename);
2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作
·AssetManageram=null;
·am=getAssets();
·InputStreamis=am.open("filename");
注意1:Google的Android系统处理Assert有个bug,在AssertManager中不能处理单个超过1MB的文件,不然会报异常,raw没这个限制可以放个4MB的Mp3文件没问题。
注意2:assets文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像xml,java文件被预编译,可以存放一些图片,html,js,css等文件。
解析如下文件
1
2
3
4
5
6
7
8<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+idtton1"
android:text="LargeText"
android:textAppearance="?android:attr/textAppearanceLarge"/>
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20XmlPullParserpullParser=Xml.newPullParser();//得到XML解析器
AssetManagerassetManager=getAssets();//文件保存在assets目录下,得到assetManager管理器
InputStreamis;
try
{
is=assetManager.open("activity_main.xml");//打开文件,得到输入流
pullParser.setInput(is,"utf-8");//StringinputEncoding格式
inteventType=pullParser.getEventType();//得到事件类型
while(eventType!=XmlPullParser.END_DOCUMENT)//文档的末尾
{//遍历内部的内容
Stringname=pullParser.getName();
if("TextView".equals(name))
{
Stringvalue=pullParser.getAttributeValue(2);//得到属性值(位置)
textView.setText("显示结果为:"+value);
break;/到就返回
}
eventType=pullParser.next();//读取下一个标签
}
}
显示结果为:
㈢ 关于android下面的xml解析
我用的是PULL解析,SAX,dom感觉都没PULL好用
public class XmlParseService
{
public static List<Person> pullXML(InputStream in)
{
try
{
//创建一个PULL解析对象
//1)XmlPullParser parse= Xml.newPullParser();
XmlPullParserFactory xmlfactory=XmlPullParserFactory.newInstance();
XmlPullParser parse=xmlfactory.newPullParser();
parse.setInput(in, "utf-8");
int eventCode=parse.getEventType();
Person person = null;
List<Person> list = null;
while(eventCode!=XmlPullParser.END_DOCUMENT)
{
switch(eventCode)
{
//开始解析文档
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Person>();
System.out.println("1111111开始文档的解析");
break;
case XmlPullParser.START_TAG:
System.out.println("2222222开始解析标记");
if("person".equals(parse.getName()))
{
person = new Person();
person.setId(parse.getAttributeValue(0));
}
else
{
if("name".equals(parse.getName()))
{
person.setName(parse.nextText());
}
else if("age".equals(parse.getName()))
{
person.setAge(parse.nextText());
}
}
break;
case XmlPullParser.END_TAG:
System.out.println("33333333结束解析标记");
if("person".equals(parse.getName()))
{
if(person!=null)
{
list.add(person);
person = null;
}
}
break;
}
eventCode = parse.next();
}
in.close();
return list;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
你自己创建一个XML,我用实体类PERSON封装的
㈣ 如何用pull解析器解析androidmanifest.xml文件
PULL解析xml:
1、核心类:
XmlPullParserFactory
XmlPullParser
2、核心代码:
// 实例化一个xml pull解析的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 实例化一个xml pull解析对象
XmlPullParser pullParser = factory.newPullParser();
// 将xml文件作为流传入到inputstream
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("customers.xml"));
// xml解析对象接收输入流对象
pullParser.setInput(bis, "utf-8");
int event = pullParser.getEventType();
List<Map<String, Object>> list = null;
Map<String, Object> map = null;
while (event != XmlPullParser.END_DOCUMENT) {
switch (event) {
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<>();
break;
case XmlPullParser.START_TAG:
if ("customer".equals(pullParser.getName())) {
map = new HashMap<String, Object>();
}
if (pullParser.getName().equals("name")) {
map.put("name", pullParser.nextText());
}
if (pullParser.getName().equals("tel")) {
map.put("tel", pullParser.nextText());
}
// if (pullParser.getName().equals("email")) {
// map.put("email", pullParser.nextText());
// }
break;
case XmlPullParser.END_TAG:
if (pullParser.getName().equals("customer")) {
list.add(map);
}
break;
}
event = pullParser.next();
}
希望能帮助你!
㈤ android开发从后台获取xml数据怎么解析
Android--3种解析XML数据的步骤
采用DOM解析时具体处理步骤是:
1 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例
2 然后利用DocumentBuilderFactory创建DocumentBuilder
3 然后加载XML文档(Document),
4 然后获取文档的根结点(Element),
5 然后获取根结点中所有子节点的列表(NodeList),
6 然后使用再获取子节点列表中的需要读取的结点。
采用SAX解析时具体处理步骤是:
1 创建SAXParserFactory对象
2 根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器
3 根据SAXParser解析器获取事件源对象XMLReader
4 实例化一个DefaultHandler对象
5 连接事件源对象XMLReader到事件处理类DefaultHandler中
6 调用XMLReader的parse方法从输入源中获取到的xml数据
7 通过DefaultHandler返回我们需要的数据集合。
采用PULL解析基本处理方式:
1:当导航到XmlPullParser.START_DOCUMENT,可以不做处理,当然你可以实例化集合对象等等。
2:当导航到XmlPullParser.START_TAG,则判断是否是river标签,如果是,则实例化river对象,并调用getAttributeValue方法获取标签中属性值。
3:当导航到其他标签,比如Introction时候,则判断river对象是否为空,如不为空,则取出Introction中的内容,nextText方法来获取文本节点内容
4:它一定会导航到XmlPullParser.END_TAG的,有开始就要有结束嘛。在这里我们就需要判读是否是river结束标签,如果是,则把river对象存进list集合中了,并设置river对象为null.
几种解析技术的比较与总结:
对于Android的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。
1 DOM在处理XML文件时,将XML文件解析成树状结构并放入内存中进行处理。当XML文件较小时,我们可以选DOM,因为它简单、直观。www.2cto.com
2 SAX则是以事件作为解析XML文件的模式,它将XML文件转化成一系列的事件,由不同的事件处理器来决定如何处理。XML文件较大时,选择SAX技术是比较合理的。虽然代码量有些大,但是它不需要将所有的XML文件加载到内存中。这样对于有限的Android内存更有效,而且Android提供了一种传统的SAX使用方法以及一个便捷的SAX包装器。
3 XML pull解析并未像SAX解析那样监听元素的结束,而是在开始处完成了大部分处理。这有利于提早读取XML文件,可以极大的减少解析时间,这种优化对于连接速度较漫的移动设备而言尤为重要。对于XML文档较大但只需要文档的一部分时,XML Pull解析器则是更为有效的方法。
。。具体你可以再查看相关资料。
㈥ Android将这xml文件用sax方式解析怎么弄
在 Android中解析XML文主要有三种方式,分别为Simple API for XML(SAX)、Document Object Model(DOM)和Android附带的PULL解析器。其中SAX是一个解析速度非常快并且占用内存少的XML解析器,非常适合Android手机等移动设备。
SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,占用内存较少(相对于DOM而言)。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在 startElement方法中,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。
使用SAX解析XML文件一般有以下五个步骤:
1、创建一个SAXParserFactory对象(通过类名很容易得知它利用工厂方法模式实现的);
2、调用SAXParserFactory中的newSAXParser方法创建一个SAXParser对象;
3、然后在调用SAXParser中的getXMLReader方法获取一个XMLReader对象;
4、在XMLReader中注册事件处理接口,一般有ContentHandler、ErrorHandler、DTDHandler、EntityHandler四种;
5、调用XMLReader中的parse方法解析指定的XML字符串对象;
步骤四中提到的四个Handler是事件处理接口,SAX的事件处理函数就定义在这四个接口中,利用SAX解析XML文件需要重写接口中的方法。其中ContentHandler用来处理XML中的内容,ErrorHandler用来处理错误,DTDHandler用来处理DTD,EntityHandler用来处理XML文档中的实体;最常用的是ContentHandler这个接口,下面是该接口中的一些常用方法:
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument()
和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElement(String uri, String localName, String qName, Attributes atts)
当读到一个开始标签的时候,会触发这个方法。uri是命名空间(通过xmlns声明),localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。注意,如果没有指定Namespace,则qName可能为空,当然不同的SAX实现会有所不同,比如在Android中qName为空,而J2SE中localName为空,所以想要总是得到标签名,就需要检查这两个参数的值了。
endElement(String uri, String localName, String name)
这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length)
这个方法用来处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。
下面是利用SAX解析XML文件的DEMO程序,首先定义一个XML文件users.xml,内容如下:
01 <?xml version="1.0" encoding="utf-8"?>
02 <users>
03 <user id="1">
04 <name>wuxianglong</name>
05 <password>199098</password>
06 </user>
07 <long:user id="2">
08 <name>wuwenyuan</name>
09 <password>199189</password>
10 </long:user>
11 </users>
其中第二个user标签中字符串long就是所谓的前缀,标签中的id则是该标签的一个属性。
然后我们来实现ContentHandler这个接口,并重写其中的方法来处理上面的XML文件,代码如下:
01 package sax.test;
02
03 import java.util.ArrayList;
04
05 import org.xml.sax.Attributes;
06 import org.xml.sax.SAXException;
07 import org.xml.sax.helpers.DefaultHandler;
08
09 public class MyHandler extends DefaultHandler {
10 private ArrayList<User> users;
11 private User user;
12 private String content;
13
14 public ArrayList<User> getUsers() {
15 return users;
16 }
17
18 @Override
19 public void startDocument() throws SAXException {
20 super.startDocument();
21 users = new ArrayList<User>();
22 System.out.println("----------Start Parse Document----------" );
23 }
24
25 @Override
26 public void endDocument() throws SAXException {
27 System.out.println("----------End Parse Document----------" );
28 }
29
30 @Override
31 public void characters(char[] ch, int start, int length)
32 throws SAXException {
33 super.characters(ch, start, length);
34 // 获得标签中的文本
35 content = new String(ch, start, length);
36 }
37
38 @Override
39 public void startElement(String uri, String localName, String qName,
40 Attributes attributes) throws SAXException {
41 super.startElement(uri, localName, qName, attributes);
42 // 打印出localname和qName
43 System.out.println("LocalName->" + localName);
44 System.out.println("QName->" + qName);
45 if ("user".equals(localName)) {
46 user = new User();
47 user.setId(Integer.parseInt(attributes.getValue("id")));
48 }
49 }
50
51 @Override
52 public void endElement(String uri, String localName, String qName)
53 throws SAXException {
54 super.endElement(uri, localName, qName);
55 if ("name".equals(localName)) {
56 user.setName(content);
57 } else if ("password".equals(localName)) {
58 user.setPassword(content);
59 } else if ("user".equals(localName)) {
60 users.add(user);
61 }
62 }
63 }
最后我们编辑TestSAX这个类,获取users.xml这个文件中的内容,并利用SAX进行解析,代码如下:
01 package sax.test;
02
03 import java.io.IOException;
04
05 import javax.xml.parsers.ParserConfigurationException;
06 import javax.xml.parsers.SAXParser;
07 import javax.xml.parsers.SAXParserFactory;
08
09 import org.xml.sax.InputSource;
10 import org.xml.sax.SAXException;
11 import org.xml.sax.XMLReader;
12
13 import android.app.Activity;
14 import android.os.Bundle;
15 import android.widget.TextView;
16
17 public class TestSAX extends Activity {
18 private TextView text;
19
20 /** Called when the activity is first created. */
21 @Override
22 public void onCreate(Bundle savedInstanceState) {
23 super.onCreate(savedInstanceState);
24 setContentView(R.layout.main);
25
26 text = (TextView) findViewById(R.id.result);
27
28 try {
29 // 创建一个工厂对象
30 SAXParserFactory factory = SAXParserFactory.newInstance();
31 // 通过工厂对象得到一个解析器对象
32 SAXParser parser = factory.newSAXParser();
33 // 通过parser得到XMLReader对象
34 XMLReader reader = parser.getXMLReader();
35 // 为reader对象注册事件处理接口
36 MyHandler handler = new MyHandler();
37 reader.setContentHandler(handler);
38 // 解析指定XML字符串对象
39 reader.parse(newInputSource(TestSAX.class.getClassLoader().getResourceAsStream("users.xml")));
40
41 String usersInfo = "";
42 for (User user : handler.getUsers()) {
43 usersInfo += "ID->" + user.getId() + "\n";
44 usersInfo += "NAME->" + user.getName() + "\n";
45 usersInfo += "PASSWORD->" + user.getPassword() + "\n";
46 usersInfo += "\n\n";
47 }
48 text.setText(usersInfo);
49 } catch (SAXException e) {
50 e.printStackTrace();
51 } catch (ParserConfigurationException e) {
52 e.printStackTrace();
53 } catch (IOException e) {
54 e.printStackTrace();
55 }
56 }
57
58 }
㈦ and android:解析xml,一个节点标签中,有多个属性,怎样解析
定义好对象关系的类。
解析以Course为例子
publicstaticList<Course>getCourseList(InputStreamstream){
List<Course>list=newArrayList<Course>();
//得到DocumentBuilderFactory对象,由该对象可以得到DocumentBuilder对象
DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
try{
//得到DocumentBuilder对象
DocumentBuilderbuilder=factory.newDocumentBuilder();
//得到代表整个xml的Document对象
Documentdocument=builder.parse(stream);
//得到"根节点"
Elementroot=document.getDocumentElement();
//获取根节点的所有items的节点
NodeListitems=root.getElementsByTagName("item");
//遍历所有节点
for(inti=0;i<items.getLength();i++){
Coursecourse=newCourse();
Elementitem=(Element)items.item(i);
course.setName(item.getAttribute("name"));
//再枚举子节点
list.add(course);
}
}catch(ParserConfigurationExceptione){
e.printStackTrace();
}catch(SAXExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
returnlist;
}
㈧ android中怎么解析复杂的xml文件
本文主要讲解Android开发中如何对XML文件的解析,由于XML文件具有与平台无关,广泛应用于数据通信中,因此解析XML文件就显得很有意义。Android对XML文件解析的方法主要有3种。 通常有三种方式:DOM、SAX和PULL,下面就分别针对这三种方式来进行讨论。
文件内容如下所示:
那么就是要对此XML文件做解析。下面我们就分别用DOM,SAX和PULL三种方式,分别对此XML文件做解析。
DOM方式
DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。由DOM解析的方式可以知道,如果XML文件很大的时候,处理效率就会变得比较低,这也是DOM方式的一个缺点。
现在我们来解析上文中提到的有关天气预报信息相关的xml文件。什么是解析呢?说的通俗一点,就是将这个带标签的XML文件识别出来,并抽取一些相关的,对我们有用的信息来给我们使用。那在这个文件里,时间,天气,温度,以及图标对我们来说是需要得到的。我们要对其做解析。
解析的具体思路是:
1. 将XML文件加载进来。
2. 获取文档的根节点
3. 获取文档根节点中所有子节点的列表
4. 获取子节点列表中需要读取的节点信息
根据这4个步骤,我们进行开发:
首先就是如何加载XML文件,假设此文件来源于网络。
SAX方式
SAX是Simple API for XML的缩写。是一个包也可以看成是一些接口。
相比于DOM而言SAX是一种速度更快,更有效,占用内存更少的解析XML文件的方法。它是逐行扫描,可以做到边扫描边解析,因此SAX可以在解析文档的任意时刻停止解析。非常适用于Android等移动设备。
SAX是基于事件驱动的。所谓事件驱动就是说,它不用解析完整个文档,在按内容顺序解析文档过程中,SAX会判断当前读到的字符是否符合XML文件语法中的某部分。如果符合某部分,则会触发事件。所谓触发事件,就是调用一些回调方法。当然android的事件机制是基于回调方法的,在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口。
这四个接口的详细说明如下:
事件处理器名称
事件处理器处理的事件
XMLReader注册方法
ContentHander
XML文档的开始与结束,
XML文档标签的开始与结束,接收字符数据,跳过实体,接收元素内容中可忽略的空白等。
setContentHandler(ContentHandler h)
DTDHander
处理DTD解析时产生的相应事件
setDTDHandler(DTDHandler h)
ErrorHandler
处理XML文档时产生的错误
setErrorHandler(ErrorHandler h)
EntityResolver
处理外部实体
setEntityResolver(EntityResolver e)
我们用来做内容解析的回调方法一般都定义在ContentHandler接口中。
ContentHandler接口常用的方法:
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument()
当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElement(String namespaceURI, String localName,String qName, Attributes atts)
当读到开始标签的时候,会调用这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。
endElement(String uri, String localName, String name)
在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length)
这个方法用来处理在XML文件中读到的内容。例如:<high data="30"/>主要目的是获取high标签中的值。
第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。
注意:
SAX的一个重要特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下之前所碰到的标签,即在startElement()方法中,所有能够知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不知道的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM方便。
现在我们截取一段XML文件来做解析,其调用方法是这样的:
<?xml version="1.0"?> ----------> startDocument()
<weather> ----------> startElement
<forecast_information> ----------> startElement
<city> ----------> startElement
beijing ----------> characters
</city> ----------> endElement
</forecast_information > ----------> endElement
</weather > ----------> endElement
文档结束 ----------> endDocument()
SAX的解析步骤:
首先需要注意的是:
SAX还为其制定了一个Helper类:DefaultHandler它实现了ContentHandler这个接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重载相应的方法即可。
使用SAX解析XML文件一般有以下五个步骤:
1、创建一个SAXParserFactory对象;
2、调用SAXParserFactory中的newSAXParser方法创建一个SAXParser对象;
3、然后在调用SAXParser中的getXMLReader方法获取一个XMLReader对象;
4、实例化一个DefaultHandler对象
5、连接事件源对象XMLReader到事件处理类DefaultHandler中
6、调用XMLReader的parse方法从输入源中获取到的xml数据
7、通过DefaultHandler返回我们需要的数据集合。
我们仍然来解析上述那个天气预报的XML文件。
编写代码如下:
[java] view plain
mySAX.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
try{
String url = "http://www.google.com/ig/api?&weather=beijing";
DefaultHttpClient client = new DefaultHttpClient();
HttpUriRequest req = new HttpGet(url);
HttpResponse resp = client.execute(req);
HttpEntity ent = resp.getEntity();
InputStream stream = ent.getContent(); //将文件导入流,因此用InputStream
SAXParserFactory saxFactory = SAXParserFactory.newInstance(); //获取一个对象
SAXParser saxParser = saxFactory.newSAXParser();//利用获取到的对象创建一个解析器
XMLContentHandler handler = new XMLContentHandler();//设置defaultHandler
saxParser.parse(stream, handler);//进行解析
stream.close();//关闭流
/*XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader(); //获取一个XMLReader
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(stream));
stream.close();*/
}catch(Exception e){
e.printStackTrace();
}
}
});
}
public class XMLContentHandler extends DefaultHandler {
private static final String TAG = "XMLContentHandler";
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
Log.i(TAG, "解析内容:"+new String(ch,start,length));
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
Log.i(TAG, "文档解析完毕。");
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.i(TAG, localName+"解析完毕");
}
@Override
public void startDocument() throws SAXException {
Log.i(TAG, "开始解析... ...");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
Log.i(TAG, "解析元素:"+localName);
if(localName.equals("high")){
Log.i(TAG, "解析元素:"+localName);
i++;
if(i==2){
highestTmp.setText(String.valueOf((Integer.parseInt(attributes.getValue(0))-32)*5/9));
}
}
}
}
上面的那段注释:
[java] view plain
/*XMLReader xmlReader =saxFactory.newSAXParser().getXMLReader(); //获取一个XMLReader
xmlReader.setContentHandler(handler);
xmlReader.parse(newInputSource(stream));
stream.close();*/
是用XMLReader来做解析的另外一种方法。效果是一样的。这里可以传流,也可以传一个字符串,如下所示:是传字符串。
[java] view plain
xmlReader.parse(new InputSource(new StringReader(xmlStr)));
PULL方式
除了可以使用 SAX和DOM解析XML文件,也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器的运行方式与 SAX 解析器相似。它也是事件触发的。Pull解析方式让应用程序完全控制文档该怎么样被解析。比如开始和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。通过Parser.getEventType()方法来取得事件的代码值,解析是在开始时就完成了大部分处理。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。
Pull解析是一个遍历文档的过程,每次调用next(),nextTag(), nextToken()和nextText()都会向前推进文档,并使Parser停留在某些事件上面,但是不能倒退。然后把文档设置给Parser。
Android中对Pull方法提供了支持的API,主要是
org.xmlpull.v1.XmlPullParser;
org.xmlpull.v1.XmlPullParserFactory;
二个类,其中主要使用的是XmlPullParser,XmlPullParserFactory是一个工厂,用于构建XmlPullParser对象。
应用程序通过调用XmlPullParser.next()等方法来产生Event,然后再处理Event。
我们仍然拿上述天气预报的XML文件的一部分来做例子。
例如:需要解析的XML文件是:
[java] view plain
<forecast_conditions>
<day_of_week data="周三"/>
<low data="22"/>
<high data="29"/>
<icon data="/ig/images/weather/chance_of_rain.gif"/>
<condition data="可能有雨"/>
</forecast_conditions>
这部分XML文件中day_of_week,low,high等是TAG,data是ATTRIBUTEA。当然,如果有<></>夹在开始和结束符号之间的部分,则为TXET。
要想解析文档先要构建一个XmlPullParser对象。
[java] view plain
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
final XmlPullParser parser = factory.newPullParser();
parser.setInput(new StringReader("xmlStr");
这里的xmlStr就是上边的XML文件。
此时,文档刚被初始化,所以它应该位于文档的开始,事件为START_DOCUMENT,可以通过XmlPullParser.getEventType()来获取。然后调用next()会产生
START_TAG,这个事件告诉应用程序一个标签已经开始了,调用getName()会返回" day_of_week ";若有TEXT,则再next()会产生TEXT事件,调用getText()会返回TEXT,由于此处没有,所以再next(),会产生END_TAG,这个告诉你一个标签已经处理完了,再next()直到最后处理完TAG,会产生END_DOCUMENT,它告诉你整个文档已经处理完成了。除了next()外,nextToken()也可以使用,只不过它会返回更加详细的事件,比如COMMENT, CDSECT, DOCDECL, ENTITY等等非常详细的信息。如果程序得到比较底层的信息,可以用nextToken()来驱动并处理详细的事件。需要注意一点的是TEXT事件是有可能返回空白的White Spaces比如换行符或空格等。
nextTag()--会忽略White Spaces,如果可以确定下一个是START_TAG或END_TAG,就可以调用nextTag()直接跳过去。通常它有二个用处:当START_TAG时,如果能确定这个TAG含有子TAG,那么就可以调用nextTag()产生子标签的START_TAG事件;当END_TAG时,如果确定不是文档结尾,就可以调用nextTag()产生下一个标签的START_TAG。在这二种情况下如果用next()会有TEXT事件,但返回的是换行符或空白符。
nextText()--只能在START_TAG时调用。当下一个元素是TEXT时,TEXT的内容会返回;当下一个元素是END_TAG时,也就是说这个标签的内容为空,那么空字串返回;这个方法返回后,Parser会停在END_TAG上。
小结一下,如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式或DOM方式会对整个文档进行解析,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。使用PULL方式正合适。
当点击三种方式的任何一个按钮时,均能够得到相同的结果
㈨ 在android中怎么使用pullparse解析.xml文件
Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。
下面我们通过Demo例子来介绍如何使用PULL机制来解析XML文件。先看下如下工程的目录结构:
按以下步骤进行操作:
[1] 新建一个XML文件,命名为student.xml。同时把XML文件放置到assets目录下。student.xml文件的内容如下:
[html] view plain
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="20110806100">
<name>小明</name>
<age>22</age>
<sex>男</sex>
</student>
<student id="20110806101">
<name>小李</name>
<age>24</age>
<sex>男</sex>
</student>
<student id="20110806102">
<name>小丽</name>
<age>21</age>
<sex>女</sex>
</student>
</students>
[2] 根据XML文件中的节点目录,创建一个相对应的实体类,来保存解析的相应信息。在包:com.andyidea.entity下新建Student.java类。
[html] view plain
package com.andyidea.entity;
public class Student {
private String id;
private String name;
private int age;
private String sex;
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 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;
}
}
[3] 定义一个使用PULL解析XML文件的工具类:ParserByPULL.java。
[html] view plain
package com.andyidea.util;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Xml;
import com.andyidea.entity.Student;
public class ParserByPULL {
//采用XmlPullParser来解析XML文件
public static List<Student> getStudents(InputStream inStream) throws Throwable
{
List<Student> students = null;
Student mStudent = null;
//========创建XmlPullParser,有两种方式=======
//方式一:使用工厂类XmlPullParserFactory
XmlPullParserFactory pullFactory = XmlPullParserFactory.newInstance();
XmlPullParser parser = pullFactory.newPullParser();
//方式二:使用Android提供的实用工具类android.util.Xml
//XmlPullParser parser = Xml.newPullParser();
//解析文件输入流
parser.setInput(inStream, "UTF-8");
//产生第一个事件
int eventType = parser.getEventType();
//只要不是文档结束事件,就一直循环
while(eventType!=XmlPullParser.END_DOCUMENT)
{
switch (eventType)
{
//触发开始文档事件
case XmlPullParser.START_DOCUMENT:
students = new ArrayList<Student>();
break;
//触发开始元素事件
case XmlPullParser.START_TAG:
//获取解析器当前指向的元素的名称
String name = parser.getName();
if("student".equals(name))
{
//通过解析器获取id的元素值,并设置student的id
mStudent = new Student();
mStudent.setId(parser.getAttributeValue(0));
}
if(mStudent!=null)
{
if("name".equals(name))
{
//获取解析器当前指向元素的下一个文本节点的值
mStudent.setName(parser.nextText());
}
if("age".equals(name))
{
//获取解析器当前指向元素的下一个文本节点的值
mStudent.setAge(new Short(parser.nextText()));
}
if("sex".equals(name))
{
//获取解析器当前指向元素的下一个文本节点的值
mStudent.setSex(parser.nextText());
}
}
break;
//触发结束元素事件
case XmlPullParser.END_TAG:
//
if("student".equals(parser.getName()))
{
students.add(mStudent);
mStudent = null;
}
break;
default:
break;
}
eventType = parser.next();
}
return students;
}