首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

android XML累积

2012-12-27 
android XML积累JAVA中如果URL中含有中文 需要用?java.net.URLEncoder 类对中文字符进行处理,同理 ?URL中

android XML积累

JAVA中如果URL中含有中文 需要用?java.net.URLEncoder 类对中文字符进行处理,

同理 ?URL中的中文字符需要用?java.net.URLDecoder?类进行反处理。

?

以下是转载 ?地址:http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.html

?

?在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。最近做了一个android版的CSDN阅读器,用到了其中的两种(sax,pull),今天对android解析xml的这三种方式进行一次总结。

? ? ?今天解析的xml示例(channels.xml)如下:

?

<?xml version="1.0" encoding="utf-8"?><channel><item id="0" url="http://www.baidu.com">百度</item><item id="1" url="http://www.qq.com">腾讯</item><item id="2" url="http://www.sina.com.cn">新浪</item><item id="3" url="http://www.taobao.com">淘宝</item></channel>

?一、使用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 localName, String qName) 接收文档结束的标签

? ? 在一般使用中为了简化开发,在org.xml.sax.helpers提供了一个DefaultHandler类,它实现了ContentHandler的方法,我们只想继承DefaultHandler方法即可。

? ?另外SAX解析器提供了一个工厂类:SAXParserFactory,SAX的解析类为SAXParser 可以调用它的parser方法进行解析。

? ?看了些基础以后开始上代码吧(核心代码,下载代码在附件)

?

public class SAXPraserHelper extends DefaultHandler {      final int ITEM = 0x0005;      List<channel> list;     channel chann;     int currentState = 0;      public List<channel> getList() {         return list;     }      /*      * 接口字符块通知 */     @Override     public void characters(char[] ch, int start, int length)             throws SAXException {         // TODO Auto-generated method stub // super.characters(ch, start, length);         String theString = String.valueOf(ch, start, length);         if (currentState != 0) {             chann.setName(theString);             currentState = 0;         }         return;     }      /*      * 接收文档结束通知 */     @Override     public void endDocument() throws SAXException {         // TODO Auto-generated method stub         super.endDocument();     }      /*      * 接收标签结束通知 */     @Override     public void endElement(String uri, String localName, String qName)             throws SAXException {         // TODO Auto-generated method stub         if (localName.equals("item"))             list.add(chann);     }      /*      * 文档开始通知 */     @Override     public void startDocument() throws SAXException {         // TODO Auto-generated method stub         list = new ArrayList<channel>();     }      /*      * 标签开始通知 */     @Override     public void startElement(String uri, String localName, String qName,             Attributes attributes) throws SAXException {         // TODO Auto-generated method stub         chann = new channel();         if (localName.equals("item")) {             for (int i = 0; i < attributes.getLength(); i++) {                 if (attributes.getLocalName(i).equals("id")) {                     chann.setId(attributes.getValue(i));                 } else if (attributes.getLocalName(i).equals("url")) {                     chann.setUrl(attributes.getValue(i));                 }             }             currentState = ITEM;             return;         }         currentState = 0;         return;     } }

?

?

private List<channel> getChannelList() throws ParserConfigurationException, SAXException, IOException     {         //实例化一个SAXParserFactory对象         SAXParserFactory factory=SAXParserFactory.newInstance();         SAXParser parser;         //实例化SAXParser对象,创建XMLReader对象,解析器         parser=factory.newSAXParser();         XMLReader xmlReader=parser.getXMLReader();         //实例化handler,事件处理器         SAXPraserHelper helperHandler=new SAXPraserHelper();         //解析器注册事件         xmlReader.setContentHandler(helperHandler);         //读取文件流         InputStream stream=getResources().openRawResource(R.raw.channels);         InputSource is=new InputSource(stream);         //解析文件         xmlReader.parse(is);         return helperHandler.getList();     }

?

?

?

从第二部分代码,可以看出使用SAX解析XML的步骤:

1、实例化一个工厂SAXParserFactory

2、实例化SAXPraser对象,创建XMLReader 解析器

3、实例化handler,处理器

4、解析器注册一个事件

4、读取文件流

5、解析文件

二、使用pull方式解析

基础知识:

? ? ? 在android系统中,很多资源文件中,很多都是xml格式,在android系统中解析这些xml的方式,是使用pul解析器进行解析的,它和sax解析一样(个人感觉要比sax简单点),也是采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。

其实以上描述,就是对整个解析步骤的一个描述,看看代码吧

?

private List<Map<String, String>> getData() {         List<Map<String, String>> list = new ArrayList<Map<String, String>>();         XmlResourceParser xrp = getResources().getXml(R.xml.channels);          try {             // 直到文档的结尾处             while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {                 // 如果遇到了开始标签                 if (xrp.getEventType() == XmlResourceParser.START_TAG) {                     String tagName = xrp.getName();// 获取标签的名字                     if (tagName.equals("item")) {                         Map<String, String> map = new HashMap<String, String>();                         String id = xrp.getAttributeValue(null, "id");// 通过属性名来获取属性值                         map.put("id", id);                         String url = xrp.getAttributeValue(1);// 通过属性索引来获取属性值                         map.put("url", url);                         map.put("name", xrp.nextText());                         list.add(map);                     }                 }                 xrp.next();// 获取解析下一个事件             }         } catch (XmlPullParserException e) {             // TODO Auto-generated catch block             e.printStackTrace();         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }          return list;     }
?

?

?

?

三、使用Dom方式解析

基础知识:

? ? ?最后来看看Dom解析方式,这种方式解析自己之前也没有用过(在j2ee开发中比较常见,没有做过这方面的东西),在Dom解析的过程中,是先把dom全部文件读入到内存中,然后使用dom的api遍历所有数据,检索想要的数据,这种方式显然是一种比较消耗内存的方式,对于像手机这样的移动设备来讲,内存是非常有限的,所以对于比较大的XML文件,不推荐使用这种方式,但是Dom也有它的优点,它比较直观,在一些方面比SAX方式比较简单。在xml文档比较小的情况下也可以考虑使用dom方式。

Dom方式解析的核心代码如下:

?

?

public static List<channel> getChannelList(InputStream stream)     {         List<channel> list=new ArrayList<channel>();                  //得到 DocumentBuilderFactory 对象, 由该对象可以得到 DocumentBuilder 对象         DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();                  try {             //得到DocumentBuilder对象             DocumentBuilder builder=factory.newDocumentBuilder();             //得到代表整个xml的Document对象             Document document=builder.parse(stream);             //得到 "根节点"              Element root=document.getDocumentElement();             //获取根节点的所有items的节点             NodeList items=root.getElementsByTagName("item");               //遍历所有节点             for(int i=0;i<items.getLength();i++)             {                 channel chann=new channel();                 Element item=(Element)items.item(i);                 chann.setId(item.getAttribute("id"));                 chann.setUrl(item.getAttribute("url"));                 chann.setName(item.getFirstChild().getNodeValue());                 list.add(chann);             }                      } catch (ParserConfigurationException e) {             // TODO Auto-generated catch block             e.printStackTrace();         } catch (SAXException e) {             // TODO Auto-generated catch block             e.printStackTrace();         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }                  return list;     }

?

总结一下Dom解析的步骤(和sax类似)

1、调用 DocumentBuilderFactory.newInstance() 方法得到 DOM 解析器工厂类实例。

2、调用解析器工厂实例类的?newDocumentBuilder() 方法得到 DOM 解析器对象

3、调用 DOM 解析器对象的 parse()?方法解析 XML 文档得到代表整个文档的 Document 对象。

四、总结

? ? ? ?除以上三种外还有很多解析xml的方法,比如DOM4J、JDOM等等。但其基本的解析方式包含两种,一种是事件驱动的(代表SAX),另一种方式是基于文档结构(代表DOM)。其他的只不过语法不一样而已。

附(本文示例运行截屏):

android XML累积

?

android XML累积

?

下载源码

热点排行