android解析XML总结(SAX、Pull、Dom三种体式格式)

在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办法进行解析。


   看了些根蒂根基今后开端上代码吧(核心代码,下载代码在附件)



 1 public class SAXPraserHelper extends DefaultHandler {
 2 
 3     final int ITEM = 0 x0005;
 4 
 5     List<channel> list;
 6     channel chann;
 7     int currentState = 0;
 8 
 9     public List<channel> getList() {
10         return list;
11     }
12 
13     /*
14      * 接口字符块通知
15 */
16     @Override
17     public void characters(char[] ch, int start, int length)
18             throws SAXException {
19         // TODO Auto-generated method stub
20 // super.characters(ch, start, length);
21         String theString = String.valueOf(ch, start, length);
22         if (currentState != 0) {
23             chann.setName(theString);
24             currentState = 0;
25         }
26         return;
27     }
28 
29     /*
30      * 接管文档停止通知
31 */
32     @Override
33     public void endDocument() throws SAXException {
34         // TODO Auto-generated method stub
35         super.endDocument();
36     }
37 
38     /*
39      * 接管标签停止通知
40 */
41     @Override
42     public void endElement(String uri, String localName, String qName)
43             throws SAXException {
44         // TODO Auto-generated method stub
45         if (localName.equals("item"))
46             list.add(chann);
47     }
48 
49     /*
50      * 文档开端通知
51 */
52     @Override
53     public void startDocument() throws SAXException {
54         // TODO Auto-generated method stub
55         list = new ArrayList<channel>();
56     }
57 
58     /*
59      * 标签开端通知
60 */
61     @Override
62     public void startElement(String uri, String localName, String qName,
63             Attributes attributes) throws SAXException {
64         // TODO Auto-generated method stub
65         chann = new channel();
66         if (localName.equals("item")) {
67             for (int i = 0; i < attributes.getLength(); i++) {
68                 if (attributes.getLocalName(i).equals("id")) {
69                     chann.setId(attributes.getValue(i));
70                 } else if (attributes.getLocalName(i).equals("url")) {
71                     chann.setUrl(attributes.getValue(i));
72                 }
73             }
74             currentState = ITEM;
75             return;
76         }
77         currentState = 0;
78         return;
79     }
80 }



 1 private List<channel> getChannelList() throws ParserConfigurationException, SAXException, IOException
 2     {
 3         //实例化一个SAXParserFactory对象
 4         SAXParserFactory factory=SAXParserFactory.newInstance();
 5         SAXParser parser;
 6         //实例化SAXParser对象,创建XMLReader对象,解析器
 7         parser=factory.newSAXParser();
 8         XMLReader xmlReader=parser.getXMLReader();
 9         //实例化handler,事务处理惩罚器
10         SAXPraserHelper helperHandler=new SAXPraserHelper();
11         //解析器注册事务
12         xmlReader.setContentHandler(helperHandler);
13         //读取文件流
14         InputStream stream=getResources().openRawResource(R.raw.channels);
15         InputSource is=new InputSource(stream);
16         //解析文件
17         xmlReader.parse(is);
18         return helperHandler.getList();
19     }


从第二项目组代码,可以看出应用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()获取本节点的值。


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



 1 private List<Map<String, String>> getData() {
 2         List<Map<String, String>> list = new ArrayList<Map<String, String>>();
 3         XmlResourceParser xrp = getResources().getXml(R.xml.channels);
 4 
 5         try {
 6             // 直到文档的结尾处
 7             while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {
 8                 // 若是碰到了开端标签
 9                 if (xrp.getEventType() == XmlResourceParser.START_TAG) {
10                     String tagName = xrp.getName();// 获取标签的名字
11                     if (tagName.equals("item")) {
12                         Map<String, String> map = new HashMap<String, String>();
13                         String id = xrp.getAttributeValue(null, "id");// 经由过程属性名来获取属性值
14                         map.put("id", id);
15                         String url = xrp.getAttributeValue(1);// 经由过程属性索引来获取属性值
16                         map.put("url", url);
17                         map.put("name", xrp.nextText());
18                         list.add(map);
19                     }
20                 }
21                 xrp.next();// 获取解析下一个事务
22             }
23         } catch (XmlPullParserException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         } catch (IOException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30 
31         return list;
32     }


 


三、应用Dom体式格式解析


根蒂根基常识:


     最后来看看Dom解析体式格式,这种体式格式解析本身之前也没有效过(在j2ee开辟中斗劲常见,没有做过这方面的器材),在Dom解析的过程中,是先把dom全部文件读入到内存中,然后应用dom的api遍历所稀有据,检索想要的数据,这种体式格式显然是一种斗劲消费内存的体式格式,对于像手机如许的移动设备来讲,内存是很是有限的,所以对于斗劲大的XML文件,不推荐应用这种体式格式,然则Dom也有它的长处,它斗劲直观,在一些方面比SAX体式格式斗劲简单。在xml文档斗劲小的景象下也可以推敲应用dom体式格式。


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



 1 public static List<channel> getChannelList(InputStream stream)
 2     {
 3         List<channel> list=new ArrayList<channel>();
 4         
 5         //获得 DocumentBuilderFactory 对象, 由该对象可以获得 DocumentBuilder 对象
 6         DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
 7         
 8         try {
 9             //获得DocumentBuilder对象
10             DocumentBuilder builder=factory.newDocumentBuilder();
11             //获得代表全部xml的Document对象
12             Document document=builder.parse(stream);
13             //获得 "根节点" 
14             Element root=document.getDocumentElement();
15             //获取根节点的所有items的节点
16             NodeList items=root.getElementsByTagName("item");  
17             //遍历所有节点
18             for(int i=0;i<items.getLength();i++)
19             {
20                 channel chann=new channel();
21                 Element item=(Element)items.item(i);
22                 chann.setId(item.getAttribute("id"));
23                 chann.setUrl(item.getAttribute("url"));
24                 chann.setName(item.getFirstChild().getNodeValue());
25                 list.add(chann);
26             }
27             
28         } catch (ParserConfigurationException e) {
29             // TODO Auto-generated catch block
30             e.printStackTrace();
31         } catch (SAXException e) {
32             // TODO Auto-generated catch block
33             e.printStackTrace();
34         } catch (IOException e) {
35             // TODO Auto-generated catch block
36             e.printStackTrace();
37         }
38         
39         return list;
40     }


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


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


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


3、调用 DOM 解析器对象的 parse() 办法解析 XML 文档获得代表全部文档的 Document 对象。


四、总结


       除以上三种外还有很多解析xml的办法,比如DOM4J、JDOM等等。但其根蒂根基的解析体式格式包含两种,一种是事务驱动的(代表SAX),另一种体式格式是基于文档布局(代表DOM)。其他的只不过语法不一样罢了。


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


  



 


下载源码

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值