Andorid xml文件的PULL解析

前端之家收集整理的这篇文章主要介绍了Andorid xml文件的PULL解析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在Android应用中的XML文件来源


1、本地xml文件

本地XML文件可以放在应用根目录assets文件夹、res/xml、res/raw、SDcard卡、应用的data目录等;

除res/xml可直接通过getXml(int id)获取XML文档,返回一个解析器对象(XmlResourceParer:XmlResourceParer是XmlPullParser的子类),其它位置情况都可以获取XML文档,返回一个Inputstream对象,进行读取数据,获取方法分别如下:

a.在res/xml目录下(推荐使用):

    public XmlResourceParser getXMLFromResXml(String fileName){  
        XmlResourceParser xmlParser = null;  
        try {          
              xmlParser = this.getResources().getXml(R.xml.provinceandcity);         
             // xml文件在res目录下 也可以用此方法返回inputStream  
             InputStream inputStream = this.getResources().openRawResource(R.xml.provinceandcity);               
             return xmlParser; 
        } catch (Exception e) {  
             e.printStackTrace();  
        }
        return null;
    }
 

b.在assets文件夹下:

    public InputStream getInputStreamFromAssets(String fileName){ 
     try { 
      InputStream inputStream = getResources().getAssets().open(fileName); 
      return inputStream; 
      } catch (IOException e) { 
     e.printStackTrace(); 
      } 
      return null; 
    } 

c.在应用指定目录下(SDcard,应用data目录等):

    public InputStream getInputStreamFromSDcard(String fileName){ 
     try { 
     // 路径根据实际项目修改 
     String path = Environment.getExternalStorageDirectory().toString() + "/test_xml/"; 
     File xmlFlie = new File(path+fileName); 
  
     InputStream inputStream = new FileInputStream(xmlFlie); 
 
     return inputStream; 
      } catch (IOException e) { 
     e.printStackTrace(); 
      } 
     return null; 
    } 

 
 

2、通过url得到的xml文件

很多时候需要解析xml文件都用于客户端与服务器之间的数据交互,比如解析google天气预报信息,或自己项目内定的一些XML数据结构,其中通过URL,使用DefaultHTTPClient get请求获取XML文件方法如下:

    /** 
     * 读取url的xml资源 转成String 
     * @param url 
     * @return 返回 读取url的xml字符串 
     */  
    public String getStringByUrl(String url) {  
        String outputString = "";  
        // DefaultHttpClient  
        DefaultHttpClient httpclient = new DefaultHttpClient();  
        // HttpGet  
        HttpGet httpget = new HttpGet(url);  
        // ResponseHandler  
        ResponseHandler<String> responseHandler = new BasicResponseHandler();  
      
        try {  
            outputString = httpclient.execute(httpget,responseHandler);  
            outputString = new String(outputString.getBytes("ISO-8859-1"),"utf-8");    // 解决中文乱码       
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        httpclient.getConnectionManager().shutdown();  
        return outputString;  
    }  

XML文件的解析方式

能够运用在Android系统上解析XML文件的常用有三种方式:DOM、SAX和PULL。
DOM解析XML是先把XML文件读进内存中,再通过接口获取数据,该方法使用相对小的XML文件,移动设备往往受硬件性能影响,如果XML文件比较大使用DOM解析往往效率跟不上。
SAX和PULL都是采用事件驱动方式来进行解析,在Android中的事件机制是基于回调函数
本例旨在考虑简单方便性,综合考虑选择了PULL解析,PULL解析器是一个开源项目,Android平台已经内置了PULL解析器,同时Android系统本身也是使用PULL解析器来解析各种XML文档。

1、事件回调类型

PULL解析XML文件时,回调XmlResourceParser内定义表示文档开头结束和节点开头结束的数值(事件回调类型),表示如下:
a.读取到XML文档开头(声明)返回:XmlPullParser.START_DOCUMENT(0)
b.读取到XML文档结束返回:XmlPullParser.END_DOCUMENT (1)
c.读取到XML节点开始返回:XmlPullParser.START_TAG (2)
d.读取到XML节点结束返回:XmlPullParser.END_TAG (3)
e.读取到XML文本返回:XmlPullParser.TEXT (4)

2、XmlPullParser有几个主要方法(更多查阅Android APIs):

a.XmlPullParser.getEventType() : Returns the type of the current event (START_TAG,END_TAG,TEXT,etc.) 【获取当前事件回调类型】
b.XmlPullParser.getName():For START_TAG or END_TAG events,the (local) name of the current element is returned when namespaces are enabled.【获取当前节点名字】
c.XmlPullParser.getAttributeValue(int index):Returns the given attributes value.【根据id获取节点属性值】
d.XmlPullParser.getAttributeValue(String namespace,String name):Returns the attributes value identified by namespace URI and namespace localName.【根据name获取节点属性值】
e.XmlPullParser.netxText():If current event is START_TAG then if next element is TEXT then element content is returned or if next event is END_TAG then empty string is returned,otherwise exception is thrown.【回调节点START_TAG时,通过此方法获取节点内容

3、实际编码中如何使用

在实际编码中,主要根据事件回调类型,结合被解析的XML结构进行解析提取数据,PULL解析XML文件的主要模式如下,更具体使用看本文提供的例子:

    try {  
        //开始解析事件  
        int eventType = parser.getEventType();  
      
        //处理事件,不碰到文档结束就一直处理  
        while (eventType != XmlPullParser.END_DOCUMENT) {   
            //因为定义了一堆静态常量,所以这里可以用switch  
            switch (eventType) {  
                case XmlPullParser.START_DOCUMENT:  
                    // 不做任何操作或初开始化数据  
                    break;  
      
                case XmlPullParser.START_TAG:  
                    // 解析XML节点数据  
                    // 获取当前标签名字  
                    String tagName = parser.getName();  
      
                    if(tagName.equals("XXXTAGXXX")){  
      
                        // 通过getAttributeValue 和 netxText解析节点的属性值和节点值  
      
                    }  
                    break;  
      
                case XmlPullParser.END_TAG:  
                    // 单节点完成,可往集合里边添加新的数据  
                    break;  
                case XmlPullParser.END_DOCUMENT:  
      
                    break;  
            }  
      
            // 别忘了用next方法处理下一个事件,不然就会死循环  
            eventType = parser.next();  
        }  
    } catch (XmlPullParserException e) {  
        e.printStackTrace();  
    }catch (IOException e) {  
        e.printStackTrace();  
    }  

运用例子

解析XML例子

    <?xml version="1.0" encoding="UTF-8"?>  
    <books>  
       <book id="1001">  
          <name>Thinking In Java</name>  
          <price>80.0</price>  
       </book>  
       <book id="1002">  
         <name>Core Java</name>  
         <price>90.0</price>  
       </book>  
       <book id="1003">  
         <name>Hello,Andriod</name>  
         <price>100.0</price>  
       </book>  
    </books> 
接下来,就该介绍操作过程了。

先定义一个Book.java的代码

    public class Book {
	private int id;
	private String name;
	private float price;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "id:" + id + ",name:" + name + ",price:" + price;
	}
    }

为解析器定义一个BookParser接口,每种类型的解析器需要实现此接口。BookParser.java代码如下:

    import java.io.InputStream;
    import java.util.List;
    import com.scott.xml.model.Book;

    public interface BookParser {
	/**
	 * 解析输入流 得到Book对象集合
	 * @param is
	 * @return
	 * @throws Exception
	 */
  	public List<Book> parse(InputStream is) throws Exception;
	
	/**
	 * 序列化Book对象集合 得到XML形式的字符串
	 * @param books
	 * @return
	 * @throws Exception
	 */
	public String serialize(List<Book> books) throws Exception;
     }
然后Pull解析PullBookParser.java代码如下:
   import java.io.InputStream;
   import java.io.StringWriter;
   import java.util.ArrayList;
   import java.util.List;
   import org.xmlpull.v1.XmlPullParser;
   import org.xmlpull.v1.XmlSerializer;
   import android.util.Xml;
   import com.scott.xml.model.Book;

    public class PullBookParser implements BookParser {
 
     @Override
     public List<Book> parse(InputStream is) throws Exception {
      List<Book> books = null;
      Book book = null;
  
//    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//    XmlPullParser parser = factory.newPullParser();
  
      XmlPullParser parser = Xml.newPullParser(); //由android.util.Xml创建一个XmlPullParser实例
      parser.setInput(is,"UTF-8");    //设置输入流 并指明编码方式

      int eventType = parser.getEventType();
      while (eventType != XmlPullParser.END_DOCUMENT) {
       switch (eventType) {
           case XmlPullParser.START_DOCUMENT:
             books = new ArrayList<Book>();
             break;
           case XmlPullParser.START_TAG:
             if (parser.getName().equals("book")) {
               book = new Book();
             } else if (parser.getName().equals("id")) {
               eventType = parser.next();
               book.setId(Integer.parseInt(parser.getText()));
             } else if (parser.getName().equals("name")) {
               eventType = parser.next();
               book.setName(parser.getText());
             } else if (parser.getName().equals("price")) {
               eventType = parser.next();
               book.setPrice(Float.parseFloat(parser.getText()));
             }
             break;
           case XmlPullParser.END_TAG:
             if (parser.getName().equals("book")) {
               books.add(book);
               book = null; 
             }
             break;
         }
         eventType = parser.next();
      }
      return books;
     }
 
     @Override
     public String serialize(List<Book> books) throws Exception {
//    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//     XmlSerializer serializer = factory.newSerializer();
  
      XmlSerializer serializer = Xml.newSerializer(); //由android.util.Xml创建一个XmlSerializer实例
      StringWriter writer = new StringWriter();
      serializer.setOutput(writer); //设置输出方向为writer
      serializer.startDocument("UTF-8",true);
      serializer.startTag("","books");
      for (Book book : books) {
       serializer.startTag("","book");
       serializer.attribute("","id",book.getId() + "");
   
       serializer.startTag("","name");
       serializer.text(book.getName());
       serializer.endTag("","name");
   
       serializer.startTag("","price");
       serializer.text(book.getPrice() + "");
       serializer.endTag("","price");
   
       serializer.endTag("","book");
       }
       serializer.endTag("","books");
       serializer.endDocument();
  
       return writer.toString();
      }
    }

主程序里使用

    try {
	   InputStream is = getAssets().open("books.xml");
	   parser = new PullBookParser();
           books = parser.parse(is);
	   for (Book book : books) {
		Log.i(TAG,book.toString());
	   }
	 } catch (Exception e) {
	    Log.e(TAG,e.getMessage());
	 }

猜你在找的XML相关文章