Android提高第七篇之XML解析与生成

本文介绍如何使用SAX解析XML文件,重点讲解了SAXParserFactory、SAXParser及XMLReader的使用方法,并通过实例展示了如何捕获XML文档中的元素、属性及文本内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 本 文使用SAX来解析XML,在Android里面可以使用SAX和DOM,DOM需要把整个XML文件读入内存再解析,比较消耗内存,而SAX基于事件驱 动的处理方式,可以在各节点触发回调函数,不过SAX适合节点结构简单的XML文档,复杂的XML文档在后期的节点深度处理会有点麻烦。

本文要解析的test.xml文件如下:

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>    
  2. < test >    
  3.   < title > testSAX </ title >    
  4.     < content   aa = "1"   bb = "2" >    
  5.       < name > hellogv </ name >    
  6.       < url > http://blog.youkuaiyun.com/hellogv </ url >    
  7.     </ content >   
  8. </ test >    
<?xml version="1.0" encoding="utf-8"?> <test> <title>testSAX</title> <content aa="1" bb="2"> <name>hellogv</name> <url>http://blog.youkuaiyun.com/hellogv</url> </content> </test>  

解析如上XML的结果如下:

 

使 用SAX解析,需要定义SAXParserFactory(使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档),SAXParser(从各种输入源解析 XML),XMLReader(使用回调函数读取 XML 文档),其中XMLReader是个关键。XMLReader可以为解析XML定义各种回调函数,“条件符合”的时候触发这些回调函数。

  1. SAXParserFactory factory = SAXParserFactory.newInstance();  
  2. SAXParser parser = factory.newSAXParser();  
  3. XMLReader reader = parser.getXMLReader();  
  4. reader.setContentHandler(handler);  
  5. reader.parse(new  InputSource(testSAX. this .getResources()  
  6.         .openRawResource(R.raw.test)));  
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setContentHandler(handler); reader.parse(new InputSource(testSAX.this.getResources() .openRawResource(R.raw.test)));

在 这段代码里,XMLReader就调用继承DefaultHandler的SAXHandler。DefaultHandler已实现 ContentHandler, DTDHandler, EntityResolver, ErrorHandler等接口,包含常见读取XML的操作,具体请看下面的SAXHandler.java源码。

生成XML的结果如下:

上图是读取各节点之后,使用XmlSerializer重新组合并输出XML字符串。

本文的main.xml代码如下:

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>   
  2. < LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"   
  3.     android:orientation = "vertical"   android:layout_width = "fill_parent"   
  4.     android:layout_height = "fill_parent" >   
  5.   
  6.     < Button   android:layout_height = "wrap_content"   
  7.         android:layout_width = "fill_parent"   android:id = "@+id/btnSAX"   
  8.         android:text = "使用SAX解析XML" > </ Button >   
  9.     < Button   android:layout_height = "wrap_content"   
  10.         android:layout_width = "fill_parent"   android:text = "生成XML"   android:id = "@+id/btnOutput" > </ Button >   
  11.     < EditText   android:text = "@+id/EditText01"   android:id = "@+id/EditText01"   
  12.         android:layout_width = "fill_parent"   android:layout_height = "fill_parent" > </ EditText >   
  13.   
  14. </ LinearLayout >   
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnSAX" android:text="使用SAX解析XML"></Button> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="生成XML" android:id="@+id/btnOutput"></Button> <EditText android:text="@+id/EditText01" android:id="@+id/EditText01" android:layout_width="fill_parent" android:layout_height="fill_parent"></EditText> </LinearLayout>

SAXHandler.java的源码如下:

  1. package  com.testSAX;  
  2.   
  3. import  java.util.ArrayList;  
  4. import  org.xml.sax.Attributes;  
  5. import  org.xml.sax.SAXException;  
  6. import  org.xml.sax.helpers.DefaultHandler;  
  7.   
  8. import  android.util.Log;  
  9.   
  10. public   class  SAXHandler  extends  DefaultHandler{  
  11.         private  ArrayList<String> keys =  new  ArrayList<String>(); //保存字段名称   
  12.         private  ArrayList<Object> values =  new  ArrayList<Object>(); //保存值   
  13.         @Override   
  14.         public   void  startDocument()  throws  SAXException {  
  15.             super .startDocument();  
  16.   
  17.         }  
  18.   
  19.         @Override   
  20.         public   void  endDocument()  throws  SAXException {  
  21.             super .endDocument();  
  22.         }  
  23.   
  24.         @Override   
  25.         public   void  startElement(String uri, String localName, String qName,  
  26.                 Attributes attributes) throws  SAXException {  
  27.             //保存开始标记   
  28.             keys.add("startTag" );  
  29.             values.add(localName);  
  30.   
  31.             Log.e("startTag" ,localName);  
  32.             //保存属性值   
  33.             for  (  int  i =  0 ; i < attributes.getLength(); i++ ){  
  34.                 keys.add("Attr" );  
  35.                 String[] str=new  String[ 2 ];  
  36.                 str[0 ]=attributes.getLocalName(i);  
  37.                 str[1 ]=attributes.getValue(i);  
  38.                 values.add(str);  
  39.                 Log.e("Attr" ,str[ 0 ]+ "=" +str[ 1 ]);  
  40.                 }  
  41.         }  
  42.   
  43.         @Override   
  44.         public   void  endElement(String uri, String localName, String qName)  
  45.                 throws  SAXException {  
  46.             //保存结束标记   
  47.             keys.add("endTag" );  
  48.             values.add(localName);  
  49.             Log.e("endTag" ,localName);  
  50.         }  
  51.   
  52.         @Override   
  53.         public   void  characters( char [] ch,  int  start,  int  length)  
  54.                 throws  SAXException {  
  55.             String value = new  String(ch, start, length);  
  56.             value = value.trim();  
  57.             if  (value.length() ==  0 )  
  58.                 return ;  
  59.               
  60.             keys.add("text" );  
  61.             values.add(value);  
  62.             Log.e("text" ,value);  
  63.         }  
  64.           
  65.         public  ArrayList<String> GetKeys()  
  66.         {  
  67.             return  keys;  
  68.         }  
  69.           
  70.         public  ArrayList<Object> GetValues()  
  71.         {  
  72.             return  values;  
  73.         }  
  74.           
  75.   
  76. }  
package com.testSAX; import java.util.ArrayList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; public class SAXHandler extends DefaultHandler{ private ArrayList<String> keys = new ArrayList<String>();//保存字段名称 private ArrayList<Object> values = new ArrayList<Object>();//保存值 @Override public void startDocument() throws SAXException { super.startDocument(); } @Override public void endDocument() throws SAXException { super.endDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //保存开始标记 keys.add("startTag"); values.add(localName); Log.e("startTag",localName); //保存属性值 for ( int i = 0; i < attributes.getLength(); i++ ){ keys.add("Attr"); String[] str=new String[2]; str[0]=attributes.getLocalName(i); str[1]=attributes.getValue(i); values.add(str); Log.e("Attr",str[0]+"="+str[1]); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //保存结束标记 keys.add("endTag"); values.add(localName); Log.e("endTag",localName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { String value = new String(ch, start, length); value = value.trim(); if (value.length() == 0) return; keys.add("text"); values.add(value); Log.e("text",value); } public ArrayList<String> GetKeys() { return keys; } public ArrayList<Object> GetValues() { return values; } }

testSAX.java的源码如下:

  1. package  com.testSAX;  
  2.   
  3. import  java.io.StringWriter;  
  4.   
  5. import  javax.xml.parsers.SAXParser;  
  6. import  javax.xml.parsers.SAXParserFactory;  
  7.   
  8. import  org.xml.sax.InputSource;  
  9. import  org.xml.sax.XMLReader;  
  10. import  org.xmlpull.v1.XmlSerializer;  
  11.   
  12. import  android.app.Activity;  
  13. import  android.os.Bundle;  
  14.   
  15. import  android.util.Xml;  
  16. import  android.view.View;  
  17. import  android.widget.Button;  
  18. import  android.widget.EditText;  
  19.   
  20. public   class  testSAX  extends  Activity {  
  21.     /** Called when the activity is first created. */   
  22.     Button btnSAX, btnOutput;  
  23.     EditText memo;  
  24.     SAXHandler handler = new  SAXHandler();  
  25.   
  26.       
  27.     @Override   
  28.     public   void  onCreate(Bundle savedInstanceState) {  
  29.         super .onCreate(savedInstanceState);  
  30.         setContentView(R.layout.main);  
  31.         btnSAX = (Button) this .findViewById(R.id.btnSAX);  
  32.         btnSAX.setOnClickListener(new  ClickEvent());  
  33.         btnOutput = (Button) this .findViewById(R.id.btnOutput);  
  34.         btnOutput.setOnClickListener(new  ClickEvent());  
  35.         memo = (EditText) this .findViewById(R.id.EditText01);  
  36.   
  37.     }  
  38.   
  39.     class  ClickEvent  implements  View.OnClickListener {  
  40.   
  41.         @Override   
  42.         public   void  onClick(View v) {  
  43.             if  (v == btnSAX) { //解析XML,并保存标记,属性等值   
  44.                 try  {  
  45.                     SAXParserFactory factory = SAXParserFactory.newInstance();  
  46.                     SAXParser parser = factory.newSAXParser();  
  47.                     XMLReader reader = parser.getXMLReader();  
  48.                     reader.setContentHandler(handler);  
  49.                     reader.parse(new  InputSource(testSAX. this .getResources()  
  50.                             .openRawResource(R.raw.test)));  
  51.                 } catch  (Exception ee) {}  
  52.             }  
  53.             else   if  (v == btnOutput) { //生成XML   
  54.                 try  {  
  55.                     XmlSerializer serializer = Xml.newSerializer();  
  56.                     StringWriter writer = new  StringWriter();  
  57.                     try  {  
  58.                         serializer.setOutput(writer);  
  59.                         serializer.startDocument("UTF-8" , true );  
  60.                           
  61.                         for ( int  i= 0 ;i<handler.GetKeys().size();i++)  
  62.                         {  
  63.                             if (handler.GetKeys().get(i).equals( "startTag" ))  
  64.                             {  
  65.                                 serializer.startTag("" , (String) handler.GetValues().get(i));  
  66.                             }  
  67.                             else   if (handler.GetKeys().get(i).equals( "Attr" )){  
  68.                                 String[] str= (String[]) handler.GetValues().get(i);  
  69.                                 serializer.attribute("" ,str[ 0 ],str[ 1 ]);  
  70.                             }  
  71.                             else   if (handler.GetKeys().get(i).equals( "text" ))  
  72.                                 serializer.text((String)handler.GetValues().get(i));  
  73.                             else   if (handler.GetKeys().get(i).equals( "endTag" ))  
  74.                             {  
  75.                                 serializer.endTag("" , (String) handler.GetValues().get(i));  
  76.                             }  
  77.                         }  
  78.                         serializer.endDocument();  
  79.                         String text=writer.toString();  
  80.                         text=text.replace("><"">\r\n<" );  
  81.                         memo.setText(text);//输出到文本框   
  82.                     } catch  (Exception e) {  
  83.                         throw   new  RuntimeException(e);  
  84.                     }  
  85.                       
  86.                 } catch  (Exception e) {}  
  87.             }  
  88.   
  89.         }  
  90.   
  91.     }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值