Android中xml文件的解析

关于xml文件的解析感觉忘得差不多了,还是记录一下学习笔记方便以后查看。

参考地址:(1)、http://blog.csdn.net/zzp16/article/details/7795410(2)、点击打开链接

在android中常见的解析方法有三种,DOM、SAX和PULL解析。其中DOM解析是先将xml文件读入内存再通过接口获取数据,该方法适用比较小的xml文件,对于大文件效率会跟不上,SAX和PULL解析都是通过事件驱动方式来进行解析,android中的事件机制基于回调函数。

本文主要讲解SAX和PULL解析。

xml文件一般存放在assets目录、res/xml或res/raw文件夹下,

(1)、assets目录用于存放需要打包到应用程序的静态文件,以便部署到设备上去,支持任意深度的子目录,不能通过R类来访问,访问形式如:

InputStream is=this.getResources().getAssets().open(fileName);

(2)、res/xml中的文件和其他资源文件一样,会被编译成二进制格式放到最终的安装包里,可以通过R类来访问其中的文件,如:

XmlResourceParser parser=this.getResources().getXml(R.xml.XXX);

其中,XmlResourceParser是XmlPullParser的子类。

(3)、res/raw中的文件会原封不动的复制到设备上,不会被编译成二进制格式,也可以通过R类来访问,如:

InputStream is=this.getResources().openRawResource(R.raw.XXX);

知道了如何获取xml文件,接下来就是解析了,自定义一个data.xml文件,如下:

<?xml version="1.0" encoding="utf-8"?>
  <Document>
    <type tname="居民点">
      <child name="城镇" code="aa" />
      <child name="农村" code="ab" />
    </type>
    <type tname="工厂点">
      <child name="工厂" code="cc" />
    </type>
  </Document>
1、PULL解析

一般将xml文件放在res/xml文件中:

public List<TypeInfo> parse() throws Exception{
    XmlResourceParser xmlParser=getResources().getXml(R.xml.data);
    int eventType=xmlParser.getEventType();
    TypeInfo typeInfo=null;
    List<TypeInfo> typeInfoList=null;
    List<ChildInfo> childList=null;
    ChildInfo childInfo=null;
    while(eventType!=XmlPullParser.END_DOCUMENT){
        switch(eventType){
            case XmlPullParser.START_DOCUMENT:
                typeInfoList=new ArrayList<TypeInfo>();
                break;
            case XmlPullParser.START_TAG:
                if(xmlParser.getName().equals("type")){
                        typeInfo=new TypeInfo();
                        typeInfo.setTname(xmlParser.getAttributeValue(0));
                        childList=new ArrayList<ChildInfo>();
                }else if(xmlParser.getName().equals("child")){//若child的格式为<child>哈哈</child>,则通过xmlParser.nextText()获取child的值
                         childInfo=new ChildInfo();
                         childInfo.setName(xmlParser.getAttributeValue(null,"name"));
                         childInfo.setCode(xmlParser.getAttributeValue(null,"code"));
                }
               break;
            case XmlPullParser.END_TAG:
               if(xmlParser.getName().equals("child")){
                   childList.add(childInfo);
               }else if(xmlParser.getName().equals("type")){
                   typeInfo.setChildList(childList);
                   typeInfoList.add(typeInfo);
               }
               break;      
      }
      eventType=xmlParser.next();
 }
 return typeInfoList;
}

若xml文件放在assets目录中,则将上述第二行代码更换为下面的代码即可

XmlPullParser xmlParser=XmlPullParser .newPullParser();
InputStream is=getResources().getAssets().open("data.xml");
xmlParser.setInput(is,"utf-8");

2、SAX解析

SAX解析会遍历完所有的节点,对于SAX解析,android有两种方式,第一种是使用org.xml.sax.helpers.DefaultHandler类进行解析,另一种是使用android自带的android.util.Xml类进行解析。

(1)、使用android自带的类进行解析(这种方法更加简单,高效)

        private List<TypeInfo> typeInfoList=new ArrayList<TypeInfo>();
	private TypeInfo typeInfo;
	private List<ChildInfo> childList;
	private ChildInfo childInfo;

    public void doParse(){
		InputStream is=getResources().openRawResource(R.raw.data);	
		RootElement root=new RootElement("Document");//根节点
		Element typeChild=root.getChild("type");
		typeChild.setElementListener(new ElementListener() {
			@Override
			public void start(Attributes attributes) {//读到元素开始时
				typeInfo=new TypeInfo();
				typeInfo.setTname(attributes.getValue("tname"));//根据属性名获取相应的值
				childList=new ArrayList<ChildInfo>();
			}
			@Override
			public void end() {//读到元素结束时
				typeInfo.setChildList(childList);
				typeInfoList.add(typeInfo);
			}
		});
		Element child=typeChild.getChild("child");
		child.setElementListener(new ElementListener() {
			@Override
			public void start(Attributes attributes) {
				childInfo=new ChildInfo();
				childInfo.setName(attributes.getValue("name"));
				childInfo.setCode(attributes.getValue("code"));
			}

			@Override
			public void end() {
				childList.add(childInfo);
			}
		});
		//若child是文本,即<child>哈哈</child>,则解析如下:
		//child.setTextElementListener(new TextElementListener() {
		//	
		//	@Override
		//	public void end(String body) {
		//		//body就是取出的字符串,即"哈哈",可在这里获取相应的值
		//	}
		//	
		//	@Override
		//	public void start(Attributes attributes) {
		//		
		//	}
		//});
		
		try {
			Xml.parse(is, Encoding.UTF_8, root.getContentHandler());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}

(2)、使用org.xml.sax.helpers.DefaultHandler类进行解析

首先定义一个SAXHandler类继承DefaultHandler,并将解析的数据放入typeInfoList中,

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

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

public class SAXHandler extends DefaultHandler {
	private List<TypeInfo> typeInfoList;
	private TypeInfo typeInfo;
	private String value;
	private List<ChildInfo> childList;
	private ChildInfo childInfo;
	public SAXHandler(List<TypeInfo> typeInfoList){
		this.typeInfoList=typeInfoList;
	}
    @Override
    public void characters(char[] ch, int start, int length)
    		throws SAXException {
    	super.characters(ch, start, length);
    	value=new String(ch, start, length);
    }
    @Override
    public void startDocument() throws SAXException {
    	super.startDocument();
    }
    @Override
    public void startElement(String uri, String localName, String qName,
    		Attributes attributes) throws SAXException {
    	super.startElement(uri, localName, qName, attributes);	
        if(localName.equalsIgnoreCase("child")){
        	childInfo=new ChildInfo();
        	childInfo.setCode(attributes.getValue("code"));
        	childInfo.setName(attributes.getValue("name"));
    	}else if(localName.equalsIgnoreCase("type")){
    		typeInfo=new TypeInfo();
    		typeInfo.setTname(attributes.getValue("tname"));
    		childList=new ArrayList<ChildInfo>();
    	}
    }
    @Override
    public void endElement(String uri, String localName, String qName)
    		throws SAXException {
    	super.endElement(uri, localName, qName);
    	if(localName.equalsIgnoreCase("child")){
    		childList.add(childInfo);
    	}else if(localName.equalsIgnoreCase("type")){
    		typeInfo.setChildList(childList);
    		typeInfoList.add(typeInfo);
    	}
    }
}

在Activity中开始解析,

//调用解析的类
		SAXParserFactory saxFactory=SAXParserFactory.newInstance();
		try {
			SAXParser saxParser=saxFactory.newSAXParser();
			XMLReader xmlReader=saxParser.getXMLReader();
			//设置解析的处理类为我们自定义的SAXHandler类
			xmlReader.setContentHandler(new SAXHandler(typeInfoList));
			//设置解析源
			InputStream is=getResources().openRawResource(R.raw.data);
			InputSource source=new InputSource(is);
			xmlReader.parse(source);
		} catch (IOException e) {
			e.printStackTrace();
		}catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
解析完成后,数据就存储在了typeInfoList中,可以显示查看

StringBuilder str=new StringBuilder();
for(int i=0;i<typeInfoList.size();i++){
	TypeInfo typeInfo=typeInfoList.get(i);
	str.append("tname=");
	str.append(typeInfo.getTname()+"\n");
	List<ChildInfo> childList=typeInfo.getChildList();
	if(childList!=null){
		str.append("child:"+"\n");
		for(int j=0;j<childList.size();j++){
			str.append("name="+childList.get(j).getName()+",");
			str.append("code="+childList.get(j).getCode()+"\n");
		}
	}
}
TextView text=(TextView) findViewById(R.id.tv_show);
text.setText(str.toString());

运行结果如下,解析成功:

tname=居民点

child:

name=城镇,code=aa

name=农村,code=ab

tname=工厂点

child:

name=工厂,code=cc





               




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值