android xml 三种解析

Introduce

xml 是目前使用范围最广的数据传输类型。这几天在弄的一个项目,就是用xml来进行数据传输的,所以特地把所有的xml 解析方式进行学习总结一下。

DOM 方式解析

Dom方式解析是将整个xml文档一次性全部读取出来,进行解析。可以想象在读入的时候,就已经将整个文档解析好了,之后可以任意地去读取出来了。

优点

这种方式很显然,读取出来方便,写入也方便。

缺点

一次性就将整个文档读取了,so,比较耗费内存。如果文档特别大,那就比较窘迫了。所以该解析方式适合文档相对较小的。对于手机,显然不合适。

代码Sample

xml文档:

 
 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <sample>
  3. <item id="0" >DOM</item>
  4. <item id="1" >SAX</item>
  5. <item id="2" >Pull</item>
  6. </sample>

以下代码都是从网上参考来的,仅供参考。

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

SAX 方式解析

sax 方式解析,是基于事件驱动的。它分成两部分,一个是xml解析器,一个事件处理器。分别对应XMLReader 和 Handler。

优点

sax不用一次性读取整个文档,很显然基于事件驱动,可以不用一次性耗费那么内存。而且,SAX解析方式更加具有结构性将xml解析器跟事件处理区分开,有人说会更麻烦,个人觉得见人见智吧,其实结构性好了,更方便使用。

缺点

一个节点一个节点地读入,如果遇到文档小,显然没有Dom那么方便。

Sample

 
 
  1. private List<Sample> getSampleList() 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. }

handle

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

Pull 方式解析

也是基于事件驱动的,但是与sax不同。它是开始解析后,可以一次一次地调用next来获取下一个解析事件,这样就多了自主地控制了。

优点

从某些角度上来看,Pull显然是要简单些。

缺点

跟SAX 优点类似吧。

Sample
 
 
  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. try {
  5. // 直到文档的结尾处
  6. while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {
  7. // 如果遇到了开始标签
  8. if (xrp.getEventType() == XmlResourceParser.START_TAG) {
  9. String tagName = xrp.getName();// 获取标签的名字
  10. if (tagName.equals("item")) {
  11. Map<String, String> map = new HashMap<String, String>();
  12. String id = xrp.getAttributeValue(null, "id");// 通过属性名来获取属性值
  13. map.put("id", id);
  14. map.put("name", xrp.nextText());
  15. list.add(map);
  16. }
  17. }
  18. xrp.next();// 获取解析下一个事件
  19. }
  20. } catch (XmlPullParserException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. } catch (IOException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. return list;
  28. }

参考

  1. http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.html

小悟诗词

穷则变,变则通,通则久 —《周易·系辞下》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值