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文件:
- <?xml version="1.0" encoding="utf-8"?>
- <workers>
- <worker id="No1">
- <name>Mark</name>
- <sex>male</sex>
- <status>CEO</status>
- <address>Beijing</address>
- <money>200000</money>
- </worker>
- <worker id="No2">
- <name>Bill</name>
- <sex>male</sex>
- <status>CTO</status>
- <address>Beijing</address>
- <money>180000</money>
- </worker>
- <worker id="No3">
- <name>Lucy</name>
- <sex>female</sex>
- <status>CFO</status>
- <address>Beijing</address>
- <money>180000</money>
- </worker>
- </workers>
源代码: main.xml
- <?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"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:id="@+id/button"
- android:layout_width="300dp"
- android:layout_height="wrap_content"
- android:text="解析XML文件"
- />
- </LinearLayout>
Android_xml.java
- package idea.org;
-
- import java.io.IOException;
- import java.io.StringReader;
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.parsers.SAXParserFactory;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class Android_xml extends Activity {
- private Button button;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- button=(Button)findViewById(R.id.button);
- button.setOnClickListener(new buttonClickListener());
- }
- class buttonClickListener implements OnClickListener
- {
-
-
-
-
- @Override
- public void onClick(View v) {
-
- new Thread()
- {
- public void run()
- {
- HttpDownloader httpDownloader=new HttpDownloader();
- String xmlStr=httpDownloader.download("http://192.168.0.5:8080/Android/test.xml");
- try {
-
- SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
-
- XMLReader reader=saxParserFactory.newSAXParser().getXMLReader();
-
- reader.setContentHandler(new MyContentHandler());
-
- reader.parse(new InputSource(new StringReader(xmlStr)));
- } catch (SAXException e) {
-
- e.printStackTrace();
- } catch (ParserConfigurationException e) {
-
- e.printStackTrace();
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- }
- }.start();
- }
-
- }
- }
MyContentHandler.java
- package idea.org;
-
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
-
- public class MyContentHandler extends DefaultHandler
- {
- private String name,sex,address,money,status,tagName;
-
-
-
- @Override
- public void startDocument() throws SAXException {
-
- System.out.println("--------开始解析--------");
- }
-
-
-
-
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
-
- tagName=localName;
- if(localName.equals("worker"))
- {
- for(int i=0;i<attributes.getLength();i++)
- System.out.println(attributes.getLocalName(i)+"="+attributes.getValue(i));
- }
- }
-
-
-
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
-
- if(tagName.equals("name"))
- name=new String(ch,start,length);
- else if(tagName.equals("sex"))
- sex=new String(ch,start,length);
- else if(tagName.equals("status"))
- status=new String(ch,start,length);
- else if(tagName.equals("address"))
- address=new String(ch,start,length);
- else if(tagName.equals("money"))
- money=new String(ch,start,length);
-
- }
-
-
-
-
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
-
- tagName="";
- if(localName.equals("worker"))
- {
- System.out.print("name:"+name);
- System.out.print(" sex:"+sex);
- System.out.print(" status:"+status);
- System.out.print(" address:"+address);
- System.out.println(" money:"+money);
- }
- }
-
-
-
-
- @Override
- public void endDocument() throws SAXException {
-
- System.out.println("--------解析结束--------");
- }
- }
HttpDownloader.java
- package idea.org;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class HttpDownloader {
- private URL url=null;
- public String download(String urlStr)
- {
- StringBuffer stringbuffer=new StringBuffer();
- String line;
- BufferedReader bufferReader=null;
- try
- {
-
- url=new URL(urlStr);
-
- HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();
-
- bufferReader=new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
- while((line=bufferReader.readLine())!=null)
- {
- stringbuffer.append(line);
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- return stringbuffer.toString();
-
- }
-
- public int download(String urlStr,String path,String fileName)
- {
- InputStream inputstream=null;
- FileUtils fileUtils=new FileUtils();
- if(fileUtils.isExist(path+fileName))
- return 1;
- else
- {
- try {
- inputstream=getFromUrl(urlStr);
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- File file=fileUtils.writeToSDPATHFromInput(path, fileName, inputstream);
- if(file!=null)
- return 0;
- else
- return -1;
- }
- }
-
- public InputStream getFromUrl(String urlStr) throws IOException
- {
- url=new URL(urlStr);
- HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();
- InputStream input=httpUrlConnection.getInputStream();
- return input;
- }
- }
FileUtil.java
- package idea.org;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import android.os.Environment;
-
-
- public class FileUtils {
- private String SDPATH=null;
- public String getSDPATH()
- {
- return SDPATH;
- }
- public FileUtils()
- {
-
- SDPATH=Environment.getExternalStorageDirectory()+"/";
- }
-
- public File createFile(String fileName) throws IOException
- {
- File file=new File(SDPATH+fileName);
- file.createNewFile();
- return file;
- }
-
- public File createDir(String fileName) throws IOException
- {
- File dir=new File(SDPATH+fileName);
- dir.mkdir();
- return dir;
- }
-
- public boolean isExist(String fileName)
- {
- File file=new File(SDPATH+fileName);
- return file.exists();
- }
- public File writeToSDPATHFromInput(String path,String fileName,InputStream inputstream)
- {
- File file=null;
- OutputStream outputstream=null;
- try
- {
- createDir(path);
- file=createFile(path+fileName);
- outputstream=new FileOutputStream(file);
- byte buffer[]=new byte[1024];
-
- while((inputstream.read(buffer))!=-1)
- {
- outputstream.write(buffer);
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- try {
- outputstream.close();
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- }
- return file;
- }
- }
AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="idea.org"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="11" />
-
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".Android_xml"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-permission android:name="android.permission.INTERNET"/>
- </manifest>
点击“解析XML文件”按钮打印以下内容: 原文地址:http://www.rosoo.net/a/201112/15511.html |