Android开发之XML文件解析

Android开发之XML文件解析



xml文件得到了越来越多的应用,我们可以用它来存储程序的配置数据,也可以在网络上以xml文件传递数据集。所以我们需要学习在Android程序中解析xml文件的方法。由于Android的开发环境是Java,所以Android程序中解析xml文件的方法和Java中解析xml文件的方法是一样的。
TAG:  XML   SAX  

xml文件得到了越来越多的应用,我们可以用它来存储程序的配置数据,也可以在网络上以xml文件传递数据集。所以我们需要学习在Android程 序中解析xml文件的方法。由于Android的开发环境是Java,所以Android程序中解析xml文件的方法和Java中解析xml文件的方法是 一样的。

1、 SAX 编程技术及SAX的处理机制 
SAX是Simple API for XML的缩写,其处理机制是建立在流和事件的基础之上,即将XML看作是“流(stream) ”,SAX“读取器”在遇到XML的“构件”(如Element,Text等)时,会产生相应的事件,然后再利用注册在“解析器”上的事件处理器时进行事 件处理。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parse()方法来开始解析XML文档并根据文档内容产生事 件。而事件处理器则是org.xml.sax包中的ContentHandler,DTDHandler,ErrorHandler,以及 EntityResolver这四个接口。它们分别处理事件源在解析过程中产生的不同种类的事件(其中DTDHandler是为解析文档DTD时而用)。 而事件源XMLReader和这四个事件处理器的连接是通过在XMLReader中的相应的事件处理器注册方法set***()来完成的。

xml框架结构图

SAX解析并不透明的进行存储及创建任何数据结构,而此类工作完全交给用户实现的事件处理器。

2、 解析器及主要的SAX API说明 
      (1)SAXParserFactory:

          其为SAXParser对象的工厂对象,使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档。

          获取该类实例的方法:SAXParserFactory.newInstance()

      (2)SAXParser(解析器)

          利用其包装的XMLReader(包装器)解析来自文件、输入流、URL中的XML,并把解析事件报告给提定的处理器。

         * 获取XMLReader方法:

          XMLReader reader=SAXParserFactory.newInstance().newSAXParser().getXMLReader();

          reader.parse(InputSource input);

     (3)DefaultHandler

         为了实现ContentHandler接口,不得不把ContentHandler中所有的抽象方法都实现,这样比较麻烦。 SAX API已经考虑到这个问题,在它的org.xml.sax.helper包中为我们提供了一个方便实现各种处理器接口的帮助类 DefaultHandler。其实现了四个核心 SAX2 处理程器接口中的所有回调(适配器模式),该类需要开发者自行继承,并实现“感兴趣”的方法。

  四个核心的SAX2处理器接口为:

  EntityResolver

  DTDHandler

  ContentHandler[H21] (构件)

  ErrorHandler

3、 事件处理器中的各个方法定义及功能 
       void startDocument():在文档开始处的事件处理方法(回调方法)

       void endDocument():在文档结束的事件处理方法

       void startElement(String uri,String lname,String qname,Attributs attrs(属性处理)):在元素开始处的事件处理方法

       void endElement(String uri,String lname,String qname):在元素结束处的事件处理方法

       uri:名字空间的URI(如果支持名字空间)

       lname:返回元素的限定名,<bean>返回bean,而<util:list>返回list(如果支持名字空间)

       qname:带前缀元素名(如果支持名字空间),如<util:list>将返回util:list

       attrs:返回该元素全部属性对象

       characters(char[] data,int index,int length):当遇到字符数据时的事件处理方法。

       data:为XML字符串构成的数组(每次根据缓冲区大小进行传递向后滚动)

       index:当前字符串中第一个字符在data中的位置

       length:当前字符串长度

4、 SAX 编程方法 
      4.1、 工作原理: 
      <bookCase>

                <book id="1">

                        <title>spring in action(中文版)</title>

               </book>

        </bookCase>

       当一个SAXParser遇到以上的XML时,依次会调 用:startDocument,startElement,startElement,startElement,characters(如内容很长可 能会有若干次),endElement, endElement, endElement,endDocument。

      4.2、 实现步骤: 
        (1)实现继承自DefalutHandler适配器的实现类,覆写“感兴趣”的方法。

        (2)获得SAXParserFactory实例。

        (3)由SAXParserFactory获得XMLReader实例。

        (4)注册处理文档内容解析事件的ContentHandler

        (5)调用XMLReader实例的parser方法,此时需给出“XML源”

示例:新建一个Android应用程序,在main.xml中添加一个按钮,当我们点击这个按钮时将会从本地tomcat服务器上下载一个xml文件,将xml文件的内容保存在String对象中。然后用SAX解析这个String对象。

需要说明的是xml源文件中各标签之间如果要有空格、Tap键等格式字符,因为SAX会把空格、Tab键解析成一个空白节点。这样的话可能会使程序不能输出我们想要显示的内容。在ContentHandler中重写处理空格的方法可以解决这个问题。这里为了简单起见,不再重写处理空格等字符的方法。

下载的xml文件:

      
      
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <workers> 
  3.     <worker id="No1"> 
  4.         <name>Mark</name> 
  5.         <sex>male</sex> 
  6.         <status>CEO</status> 
  7.         <address>Beijing</address> 
  8.         <money>200000</money> 
  9.     </worker> 
  10.     <worker id="No2"> 
  11.         <name>Bill</name> 
  12.         <sex>male</sex> 
  13.         <status>CTO</status> 
  14.         <address>Beijing</address> 
  15.         <money>180000</money> 
  16.     </worker> 
  17.     <worker id="No3"> 
  18.         <name>Lucy</name> 
  19.         <sex>female</sex> 
  20.         <status>CFO</status> 
  21.         <address>Beijing</address> 
  22.         <money>180000</money> 
  23.     </worker> 
  24. </workers> 

源代码:

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" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="fill_parent" 
  6.     > 
  7. <TextView   
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="wrap_content"  
  10.     android:text="@string/hello" 
  11.     /> 
  12. <Button 
  13.     android:id="@+id/button" 
  14.     android:layout_width="300dp" 
  15.     android:layout_height="wrap_content" 
  16.     android:text="解析XML文件" 
  17.     /> 
  18. </LinearLayout> 

Android_xml.java

      
      
  1. package idea.org; 
  2.  
  3. import java.io.IOException; 
  4. import java.io.StringReader; 
  5. import javax.xml.parsers.ParserConfigurationException; 
  6. import javax.xml.parsers.SAXParserFactory; 
  7. import org.xml.sax.InputSource; 
  8. import org.xml.sax.SAXException; 
  9. import org.xml.sax.XMLReader; 
  10. import android.app.Activity; 
  11. import android.os.Bundle; 
  12. import android.view.View; 
  13. import android.view.View.OnClickListener; 
  14. import android.widget.Button; 
  15.  
  16. public class Android_xml extends Activity { 
  17.     private Button button; 
  18.     /** Called when the activity is first created. */ 
  19.     @Override 
  20.     public void onCreate(Bundle savedInstanceState) { 
  21.         super.onCreate(savedInstanceState); 
  22.         setContentView(R.layout.main); 
  23.         button=(Button)findViewById(R.id.button); 
  24.         button.setOnClickListener(new buttonClickListener()); 
  25.     } 
  26.     class buttonClickListener implements OnClickListener 
  27.     { 
  28.  
  29.         /* (non-Javadoc) 
  30.          * @see android.view.View.OnClickListener#onClick(android.view.View) 
  31.          */      
  32.         @Override 
  33.         public void onClick(View v) { 
  34.             // TODO Auto-generated method stub 
  35.             new Thread() 
  36.             { 
  37.                 public void run() 
  38.                 { 
  39. HttpDownloader httpDownloader=new HttpDownloader(); 
  40. String xmlStr=httpDownloader.download("http://192.168.0.5:8080/Android/test.xml"); 
  41.                     try { 
  42.                         //获得SAXParser对象的工厂实例 
  43.                         SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); 
  44.                         //获得XMLReader示例 
  45.                         XMLReader reader=saxParserFactory.newSAXParser().getXMLReader(); 
  46.                         //注册处理XML文档内容解析事件的ContentHandler 
  47.                         reader.setContentHandler(new MyContentHandler()); 
  48.                         //开始解析string对象中所包含的XML资源 
  49.                         reader.parse(new InputSource(new StringReader(xmlStr))); 
  50.                     } catch (SAXException e) { 
  51.                         // TODO Auto-generated catch block 
  52.                         e.printStackTrace(); 
  53.                     } catch (ParserConfigurationException e) { 
  54.                         // TODO Auto-generated catch block 
  55.                         e.printStackTrace(); 
  56.                     } catch (IOException e) { 
  57.                         // TODO Auto-generated catch block 
  58.                         e.printStackTrace(); 
  59.                     }    
  60.                 } 
  61.             }.start();               
  62.         } 
  63.          
  64.     } 

MyContentHandler.java

      
      
  1. package idea.org; 
  2.  
  3. import org.xml.sax.Attributes; 
  4. import org.xml.sax.SAXException; 
  5. import org.xml.sax.helpers.DefaultHandler; 
  6.  
  7. public class MyContentHandler extends DefaultHandler 
  8.     private String name,sex,address,money,status,tagName; 
  9.     /* (non-Javadoc) 
  10.      * @see org.xml.sax.helpers.DefaultHandler#startDocument() 
  11.      */ 
  12.     @Override 
  13.     public void startDocument() throws SAXException { 
  14.         // TODO Auto-generated method stub 
  15.         System.out.println("--------开始解析--------"); 
  16.     } 
  17.  
  18.     /* (non-Javadoc) 
  19.      * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String
  20. , java.lang.String, java.lang.String, org.xml.sax.Attributes) 
  21.      */ 
  22.     //遇到新的标签即新的元素时执行 
  23.     @Override 
  24.     public void startElement(String uri, String localName, String qName, 
  25.             Attributes attributes) throws SAXException { 
  26.         // TODO Auto-generated method stub       
  27.         tagName=localName;//以tagName的值来判断正在解析哪个标签        
  28.         if(localName.equals("worker")) 
  29.         {//依次获取标签的全部属性 
  30.             for(int i=0;i<attributes.getLength();i++) 
  31. System.out.println(attributes.getLocalName(i)+"="+attributes.getValue(i));
  32.         } 
  33.     } 
  34.  
  35.     /* (non-Javadoc) 
  36.      * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) 
  37.      */ 
  38.     @Override 
  39.     public void characters(char[] ch, int start, int length) 
  40.             throws SAXException { 
  41.         // TODO Auto-generated method stub   
  42.         if(tagName.equals("name"))       
  43.             name=new String(ch,start,length); 
  44.         else if(tagName.equals("sex")) 
  45.             sex=new String(ch,start,length); 
  46.         else if(tagName.equals("status")) 
  47.             status=new String(ch,start,length); 
  48.         else if(tagName.equals("address"))       
  49.             address=new String(ch,start,length); 
  50.         else if(tagName.equals("money")) 
  51.             money=new String(ch,start,length); 
  52.              
  53.     } 
  54.  
  55.     /* (non-Javadoc) 
  56.      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String
  57. , java.lang.String, java.lang.String) 
  58.      */ 
  59.     //标签解析完成之后执行 
  60.     @Override 
  61.     public void endElement(String uri, String localName, String qName) 
  62.             throws SAXException { 
  63.         // TODO Auto-generated method stub   
  64.         tagName="";//清除tagName原来的值,这样在遇到空白节点时可以通过tagName识别出处理的是空白节点 
  65.         if(localName.equals("worker")) 
  66.         {//打印出所有得到的数据 
  67.             System.out.print("name:"+name); 
  68.             System.out.print("  sex:"+sex); 
  69.             System.out.print("  status:"+status); 
  70.             System.out.print("  address:"+address); 
  71.             System.out.println("  money:"+money); 
  72.         } 
  73.     } 
  74.  
  75.     /* (non-Javadoc) 
  76.      * @see org.xml.sax.helpers.DefaultHandler#endDocument() 
  77.      */ 
  78.     @Override 
  79.     public void endDocument() throws SAXException { 
  80.         // TODO Auto-generated method stub 
  81.         System.out.println("--------解析结束--------"); 
  82.     } 

HttpDownloader.java

      
      
  1. package idea.org; 
  2. import java.io.BufferedReader; 
  3. import java.io.File; 
  4. import java.io.IOException; 
  5. import java.io.InputStream; 
  6. import java.io.InputStreamReader; 
  7. import java.net.HttpURLConnection; 
  8. import java.net.URL; 
  9. public class HttpDownloader { 
  10.     private URL url=null
  11.     public String download(String urlStr) 
  12.     { 
  13.         StringBuffer stringbuffer=new StringBuffer(); 
  14.         String line; 
  15.         BufferedReader bufferReader=null
  16.         try 
  17.         { 
  18. //创建一个URL对象 
  19. url=new URL(urlStr);             
  20. //得到一个HttpURLConnection对象 
  21. HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();    
  22. // 得到IO流,使用IO流读取数据 
  23. bufferReader=new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream())); 
  24. while((line=bufferReader.readLine())!=null
  25. {                
  26. stringbuffer.append(line); 
  27. }            
  28.         } 
  29.         catch(Exception e) 
  30.         { 
  31.             e.printStackTrace(); 
  32.         }                
  33.         return stringbuffer.toString(); 
  34.          
  35.     } 
  36.     // 该函数返回整形 -1:代表下载文件出错 ;0:代表下载文件成功; 1:代表文件已经存在 
  37.     public int download(String urlStr,String path,String fileName) 
  38.     { 
  39.         InputStream inputstream=null
  40.         FileUtils fileUtils=new FileUtils(); 
  41.         if(fileUtils.isExist(path+fileName)) 
  42.             return 1
  43.         else 
  44.         { 
  45.             try { 
  46.                 inputstream=getFromUrl(urlStr); 
  47.             } catch (IOException e) { 
  48.                 // TODO Auto-generated catch block 
  49.                 e.printStackTrace(); 
  50.             } 
  51.             File file=fileUtils.writeToSDPATHFromInput(path, fileName, inputstream); 
  52.             if(file!=null
  53.                 return 0
  54.             else  
  55.                 return -1
  56.         } 
  57.     } 
  58.     //根据url字符串得到输入流 
  59.     public InputStream getFromUrl(String urlStr) throws IOException 
  60.     {        
  61.         url=new URL(urlStr);             
  62.         HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection(); 
  63.         InputStream input=httpUrlConnection.getInputStream();    
  64.         return input; 
  65.     } 

FileUtil.java

      
      
  1. package idea.org; 
  2. import java.io.File; 
  3. import java.io.FileOutputStream; 
  4. import java.io.IOException; 
  5. import java.io.InputStream; 
  6. import java.io.OutputStream; 
  7. import android.os.Environment; 
  8.  
  9.  
  10. public class FileUtils { 
  11.     private String SDPATH=null
  12.     public String getSDPATH() 
  13.     { 
  14.         return SDPATH; 
  15.     } 
  16.     public FileUtils() 
  17.     { 
  18.         //获得当前外部存储设备SD卡的目录 
  19.         SDPATH=Environment.getExternalStorageDirectory()+"/"
  20.     } 
  21.     //创建文件 
  22.     public File createFile(String fileName) throws IOException 
  23.     { 
  24.         File file=new File(SDPATH+fileName); 
  25.         file.createNewFile(); 
  26.         return file; 
  27.     } 
  28.     //创建目录 
  29.     public File createDir(String fileName) throws IOException 
  30.     { 
  31.         File dir=new File(SDPATH+fileName);      
  32.         dir.mkdir(); 
  33.         return dir; 
  34.     } 
  35.     //判断文件是否存在 
  36.     public boolean isExist(String fileName) 
  37.     { 
  38.         File file=new File(SDPATH+fileName); 
  39.         return file.exists(); 
  40.     } 
  41.     public File writeToSDPATHFromInput(String path,String fileName,InputStream inputstream) 
  42.     { 
  43.         File file=null
  44.         OutputStream outputstream=null
  45.         try 
  46.         { 
  47.             createDir(path); 
  48.             file=createFile(path+fileName); 
  49.             outputstream=new FileOutputStream(file); 
  50.             byte buffer[]=new byte[1024]; 
  51.             //将输入流中的内容先输入到buffer中缓存,然后用输出流写到文件中 
  52.             while((inputstream.read(buffer))!=-1
  53.             { 
  54.                 outputstream.write(buffer); 
  55.             } 
  56.         } 
  57.         catch(Exception e) 
  58.         { 
  59.             e.printStackTrace(); 
  60.         } 
  61.         finally 
  62.         { 
  63.             try { 
  64.                 outputstream.close(); 
  65.             } catch (IOException e) { 
  66.                 // TODO Auto-generated catch block 
  67.                 e.printStackTrace(); 
  68.             } 
  69.         } 
  70.         return file; 
  71.     } 

AndroidManifest.xml

      
      
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  3.       package="idea.org" 
  4.       android:versionCode="1" 
  5.       android:versionName="1.0"> 
  6.     <uses-sdk android:minSdkVersion="11" /> 
  7.  
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name"> 
  9.         <activity android:name=".Android_xml" 
  10.                   android:label="@string/app_name"> 
  11.             <intent-filter> 
  12.                 <action android:name="android.intent.action.MAIN" /> 
  13.                 <category android:name="android.intent.category.LAUNCHER" /> 
  14.             </intent-filter> 
  15.         </activity>        
  16.     </application> 
  17.     <uses-permission android:name="android.permission.INTERNET"/>  
  18. </manifest> 

点击“解析XML文件”按钮打印以下内容:



原文地址:http://www.rosoo.net/a/201112/15511.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值