在程序开发中,有两种语言是和平台无关的,它们就是Xml和Json,因此,作为在不同平台间传递信息的Xml和Json在Android中同样扮演者重要的角色,那么今天我们就来一起学习Android中Xml的解析吧,关于Json的解析我们将在后面的文章中和大家一起分享!
关于Xml的理论部分,这里不再赘述,如果还不知道什么是Xml,建议大家先去了解什么是Xml。在Android中解析Xml的方式有三种,分别是COM方式、SAX方式、Pull方式。今天我们将以下面的Xml文件为例,来分别讲述这三种不同的解析方式。
<?xml version="1.0" encoding="utf-8"?> <Musics> <Music ID="0" Author="许嵩">千百度</Music> <Music ID="1" Author="周杰伦">珊瑚</Music> <Music ID="2" Author="李玉刚">贵妃醉酒</Music> <Music ID="3" Author="王菲">红豆</Music> <Music ID="4" Author="孙燕姿">遇见</Music> </Musics>
一、DOM方式:DOM方式是解析Xml的传统方式,如果大家有开发过Xml相关应用的经历,理解下面的代码应该不会太难。
public class DOMParserHelper { public static List<Music> Parser(InputStream mStream) { //创建List List<Music> mMusics=new ArrayList<Music>(); //得到 DocumentBuilderFactory 对象 DocumentBuilderFactory mFactory=DocumentBuilderFactory.newInstance(); try { //得到DocumentBuilder对象 DocumentBuilder mBuilder=mFactory.newDocumentBuilder(); //得到代表整个Xml的Document对象 Document mDocument=mBuilder.parse(mStream); //得到 "根节点" Element mRoot=mDocument.getDocumentElement(); //获取根节点的所有Music的节点 NodeList mItems=mRoot.getElementsByTagName("Music"); //遍历所有Music节点 for(int i=0;i<mItems.getLength();i++) { Music m=new Music(); //获取每一个Element元素 Element mElement=(Element)mItems.item(i); //获取属性 m.setID(mElement.getAttribute("ID")); m.setAuthor(mElement.getAttribute("Author")); //获取值 m.setName(mElement.getFirstChild().getNodeValue()); //添加到List mMusics.add(m); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return mMusics; } }
二、SAX方式:SAX是Android为Xml提供的一套API,尽管DOM已经可以满足我们对于Xml解析的要求,但DOM在解析速度和资源占用等方面都存在一定的缺陷,因此官方推荐我们使用SAX来解析Xml。要使用SAX,首先就要继承DefaultHandler类并覆盖下面的方法:
public class SAXParserHandler extends DefaultHandler { private List<Music> mList; private Music m; private int mState=0; @Override public void characters(char[] ch, int start, int length)throws SAXException { String theString = String.valueOf(ch, start, length); if (mState != 0) { m.setName(theString); mState = 0; } return; } @Override public void endDocument() throws SAXException { super.endDocument(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equals("Music")) mList.add(m); } @Override public void startDocument() throws SAXException { mList=new ArrayList<Music>(); } @Override public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException { m=new Music(); if(localName.equals("Music")) { for (int i = 0; i < attributes.getLength(); i++) { if (attributes.getLocalName(i).equals("ID")) { m.setID(attributes.getValue(i)); } else if (attributes.getLocalName(i).equals("Author")) { m.setAuthor(attributes.getValue(i)); } } mState=1; return; } mState=0; return; } public List<Music> getList() { return mList; } }
在此类中,一个最为重要的方法是startElement()方法,在这这里我们定义了解析的相关规则,如果解析成功,则mState为1,否则为0。然后我们再endElement()方法中,将解析完的Music类型的值m添加到List数组中。而在characters()方法中,我们主要的工作是对节点指的解析。在实现了此接口以后,我们来看关键的代码:
public class SAXParserHelper { public static List<Music> Parser(InputStream mStream) throws ParserConfigurationException, SAXException, IOException { //实例化一个SAXParserFactory对象 SAXParserFactory mFactory=SAXParserFactory.newInstance(); SAXParser mParser; //实例化SAXParser对象,创建XMLReader对象,解析器 mParser=mFactory.newSAXParser(); XMLReader xmlReader=mParser.getXMLReader(); //实例化handler,事件处理器 SAXParserHandler mHandler=new SAXParserHandler(); //解析器注册事件 xmlReader.setContentHandler(mHandler); InputSource is=new InputSource(mStream); //解析文件 xmlReader.parse(is); return mHandler.getList(); } }
三、Pull方式:Pull方式适合解析res文件夹下的资源文件(raw文件夹除外),例如我们res文件夹下创建了一个xml文件夹,而此文件夹内包含待解析的Xml文件,此时,我们可以使用这种方式来解析Xml,关键代码如下:
public class PullParserHelper { public static List<Music> Parser(Context mContext,int XmlResourcesID) { List<Music> mList = new ArrayList<Music>(); XmlResourceParser xrp = mContext.getResources().getXml(XmlResourcesID); try { // 直到文档的结尾处 while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) { // 如果遇到了开始标签 if (xrp.getEventType() == XmlResourceParser.START_TAG) { String mTagName = xrp.getName(); if (mTagName.equals("Music")) { Music m=new Music(); m.setID(xrp.getAttributeValue(null, "ID")); m.setAuthor(xrp.getAttributeValue(null, "Author")); m.setName(xrp.nextText()); mList.add(m); } } xrp.next();// 获取解析下一个事件 } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return mList; } }
其中,Music是一个实体类,定义如下:
/* * Music实体类,用以描述歌曲相关属性 */ package com.android.XmlParser.Unitl; public class Music { private String mID; private String mName; private String mAuthor; public Music() { } public Music(String mID,String mName,String mAuthor) { this.mID=mID; this.mName=mName; this.mAuthor=mAuthor; } public String getName() { return mName; } public void setName(String mName) { this.mName = mName; } public String getAuthor() { return mAuthor; } public void setAuthor(String mAuthor) { this.mAuthor = mAuthor; } public String getID() { return mID; } public void setID(String mID) { this.mID = mID; } }程序运行效果: