国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android利用SAX對XML進行增刪改查操作詳解

2019-10-22 18:17:03
字體:
來源:轉載
供稿:網友

前言

解析XML的方式有很多種,大家比較熟悉的可能就是DOM解析。

DOM(文件對象模型)解析:解析器讀入整個文檔,然后構建一個駐留內存的樹結構,然后代碼就可以根據DOM接口來操作這個樹結構了。

  優點:整個文檔讀入內存,方便操作:支持修改、刪除和重現排列等多種功能。

  缺點:將整個文檔讀入內存中,保留了過多的不需要的節點,浪費內存和空間。

  使用場合:一旦讀入文檔,還需要多次對文檔進行操作,并且在硬件資源充足的情況下(內存,CPU)。

為了解決DOM解析存在的問題,就出現了SAX解析。其特點為:

  優點:不用實現調入整個文檔,占用資源少。尤其在嵌入式環境中,如android,極力推薦使用SAX解析。

  缺點:不像DOM解析一樣將文檔長期駐留在內存中,數據不是持久的。如果事件過后沒有保存數據,數據就會丟失。

  使用場合:機器有性能限制。

本文將給大家詳細介紹關于Android利用SAX對XML增刪改查的相關內容,分享出來供大家參考學習價值,下面話不多說了,來一起看看詳細的介紹吧。

1.概述

SAX是一中事件驅動類型的XML解析方式。說白了,就是通過復寫一個Default類去告知,解析的結果。SAX并不會想DOM那樣把整個的XML加載到內存中,而它會像IO流那樣,一個一個標簽地去解析。

簡單地說就是對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數做相應動作,然后繼續同樣的掃描,直至文檔結束。

為了方便說明,先約定好一個XML如下:

<?xml version="1.0" encoding="UTF-8"?><persons> <person id="1" key="33" type="type">  <name>zhangsan</name>  <age>21</age> </person></persons>

2.基本讀取(查)

代碼如下

SAXParserFactory factory = SAXParserFactory.newInstance();//創建SAX解析工廠SAXParser saxParser;try { File file = new File(xmlFilePath); InputStream inputStream = new FileInputStream(file);//得到輸入流 saxParser = factory.newSAXParser();//創建解析器 saxParser.parse(inputStream,new DefaultHandler(){//開始解析  //文檔開始標記  @Override  public void startDocument() throws SAXException {   super.startDocument();   Log.i("loadWithSax","startDocument");  }  //文檔結束標記  @Override  public void endDocument() throws SAXException {   super.endDocument();   FileUtils.closeIO(inputStream);   Log.i("loadWithSax","endDocument");  }  //解析到標簽  @Override  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SA   super.startElement(uri, localName, qName, attributes);   Log.i("loadWithSax","startElement"+",uri:"+uri+",localName:"+localName+",qName:"+qName);   if (attributes!=null) {    for (int i = 0; i < attributes.getLength(); i++) {     Log.i("loadWithSax",attributes.getLocalName(i)+","+attributes.getValue(i)+","+attributes.    }   }  }  //標簽解析結束  @Override  public void endElement(String uri, String localName, String qName) throws SAXException {   super.endElement(uri, localName, qName);   Log.i("loadWithSax","endElement"+",uri:"+uri+",localName:"+localName+",qName:"+qName);  }  /**   * 文本   * 該方法中的ch把所解析的xml的所有數據都保存進來,且ch初始化為2K數據。 start是一個節點">"的位置。length就是">"到下一個"<"的長度。   * <namesList>   *  <name>michael</name>   * </namesList>   * 執行namesList節點時,因為沒有文本,   * 不會執行到該方法。   */  @Override  public void characters(char[] ch, int start, int length) throws SAXException {   super.characters(ch, start, length);   Log.i("loadWithSax","characters"+",start:"+start+",length:"+length);   for (int i = 0; i < ch.length; i++) {    Log.i("loadWithSax","char:"+ch[i]+",ASCII:"+(int)ch[i]);   }  }  //警告回調  @Override  public void warning(SAXParseException e) throws SAXException {   super.warning(e);   Log.i("loadWithSax","warning"+","+e.getMessage());  }  //錯誤回調  @Override  public void error(SAXParseException e) throws SAXException {   super.error(e);   Log.i("loadWithSax","error1"+","+e.getMessage());  } });} catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); Log.i("loadWithSax","error2"+","+e.getMessage());}
  • 傳入:DefaultHandler的實體,通過復寫其中的方法,查詢到文檔,標簽的內容:
  • startDocument 和 endDocument是掃描文檔的開始和結束
  • startElement,是解析到了標簽,localName就是標簽的名稱,如本文所示例的,當解析到第一個人名的時候,
<person id="1" key="33" type="type"> <name>zhangsan</name> <age>21</age></person>

解析到<person></person>回調:startElement,標簽內的參數是Attributes attributes,一個for循環就可以遍歷讀取。

characters,解析到標簽的內容時候回調,接著上面例子,解析<person></person>,回調startElement,然后不會回調此方法,因為內容不是文本,而是包含了標簽,所以,解析到其子標簽:<name>zhangsan</name>的時候,又會先回調回調startElement,然后,才回調characters,告訴你,這個標簽里面有文本內容!參數說明如下:

  • char[] : 內容字符數組里面。如:<name>zhangsan</name>,char[]就是:{'z','h','a','n','g','s','a','n'}
  • start :0,文本的開始
  • length :文本的長度。
  • endElement,標簽結束。

使用上面的代碼,得到的部分log如下:

I/loadWithSax: startDocumentI/loadWithSax: startElement,uri:,localName:persons,qName:personsI/loadWithSax: characters,start:0,length:1I/loadWithSax: char:    ,ASCII:10I/loadWithSax: characters,start:0,length:1I/loadWithSax: char: ,ASCII:9I/loadWithSax: startElement,uri:,localName:person,qName:personI/loadWithSax: id,1,CDATAI/loadWithSax: key,33,CDATAI/loadWithSax: type,type,CDATAI/loadWithSax: characters,start:0,length:1I/loadWithSax: char:    ,ASCII:10I/loadWithSax: characters,start:0,length:2I/loadWithSax: char: ,ASCII:9I/loadWithSax: char: ,ASCII:9I/loadWithSax: startElement,uri:,localName:name,qName:nameI/loadWithSax: characters,start:0,length:8I/loadWithSax: char:z,ASCII:122I/loadWithSax: char:h,ASCII:104I/loadWithSax: char:a,ASCII:97I/loadWithSax: char:n,ASCII:110I/loadWithSax: char:g,ASCII:103I/loadWithSax: char:s,ASCII:115I/loadWithSax: char:a,ASCII:97I/loadWithSax: char:n,ASCII:110I/loadWithSax: endElement,uri:,localName:name,qName:name

startDocument,開始解析xml

解析到第一個標簽的開始:<persons>

然后解析到了內容???characters?按照我上面的分析,<persons>標簽內沒有文字內容,應該不會回調。其實,這里回調的是換行符。log中打出了ASCII碼,10就是換行。然后,還有一個tab符。

然后就是<persons>里面的<person>,有三個參數:id,key,type,巴拉巴拉。。。

3.保存

sax的保存有點麻煩。具體是XmlSerializer的使用。

初始化一個XmlSerializer:

StringWriter stringWriter = new StringWriter();XmlPullParserFactory factory = XmlPullParserFactory.newInstance();XmlSerializer xmlSerializer = factory.newSerializer();xmlSerializer.setOutput(stringWriter);

聲明文檔的開始和結束:

xmlSerializer.startDocument("utf-8", false);//false,是聲明:standalone的值。xmlSerializer.endDocument();

標簽的開始結束,和寫入內容:

xmlSerializer.startTag(null, "name");//開始,第一個參數是namespace,命名空間。xmlSerializer.text(person.name);//寫入內容xmlSerializer.endTag(null, "name");

實戰:

假如,我們需要構建如下的XML:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?><persons> <person id="1" key="33" type="type">  <name>zhangsan</name>  <age>21</age> </person> <person>  <name>lisi</name>  <age>12</age> </person> <person>  <name>wangwu</name>  <age>23</age> </person></persons>

首先你得定義好一個Bean類,Person:

public class Person { public int id = -1; public String key = null; public String type = null; public String name; public int age; public Person(String name, int age) {  this.name = name;  this.age = age; }}

然后開擼:最后的stringWriter就是你想要的數據,注意就是,一些換行和tab符。

StringWriter stringWriter = new StringWriter();try {  XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  XmlSerializer xmlSerializer = factory.newSerializer();  xmlSerializer.setOutput(stringWriter);  //制造假數據:  ArrayList<Person> personArrayList = new ArrayList<>();  Person person1 = new Person("zhangsan",21);  person1.id=1;  person1.key="33";  person1.type="type";  Person person2 = new Person("lisi",12);  Person person3 = new Person("wangwu",23);  personArrayList.add(person1);  personArrayList.add(person2);  personArrayList.add(person3);  //star document  xmlSerializer.startDocument("utf-8", true);  xmlSerializer.text("/n");  xmlSerializer.startTag(null, "persons");  for(Person person:personArrayList){    //star tag    xmlSerializer.text("/n");    xmlSerializer.text("/t");    xmlSerializer.startTag(null, "person");    //添加參數    if (person.id!=-1) {      xmlSerializer.attribute(null,"id",String.valueOf(person.id));    }    if (person.key!=null) {      xmlSerializer.attribute(null,"key",person.key);    }    if (person.type!=null) {      xmlSerializer.attribute(null,"type",person.type);    }    //添加內容:name    xmlSerializer.text("/n");    xmlSerializer.text("/t");    xmlSerializer.text("/t");    xmlSerializer.startTag(null, "name");    xmlSerializer.text(person.name);    xmlSerializer.endTag(null, "name");    //添加內容:age    xmlSerializer.text("/n");    xmlSerializer.text("/t");    xmlSerializer.text("/t");    xmlSerializer.startTag(null, "age");    xmlSerializer.text(String.valueOf(person.age));    xmlSerializer.endTag(null, "age");    //end tag    xmlSerializer.text("/n");    xmlSerializer.text("/t");    xmlSerializer.endTag(null, "person");  }  //end document  xmlSerializer.text("/n");  xmlSerializer.endTag(null, "persons");  xmlSerializer.endDocument();} catch (Exception e) {  e.printStackTrace();}

XmlSerializer的初始化需要傳入一個write對象,你可以傳入一個FileWrite,寫到文件里面:

// 創建文件對象File fileText = new File(saveFilePath);// 向文件寫入對象寫入信息FileWriter stringWriter;xmlSerializer.setOutput(stringWriter);//...同上//記得closeif (stringWriter != null) {  stringWriter.close();}

4.增刪

增加和刪除,那么你需要先對XML進行映射,映射成一堆的Bean,然后增加刪除Bean,再保存即可。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 通州市| 武宁县| 连城县| 兴宁市| 鸡西市| 丽水市| 噶尔县| 靖宇县| 灵宝市| 镇康县| 连南| 威远县| 屏东市| 察隅县| 白银市| 滦平县| 河津市| 山阳县| 石棉县| 通城县| 晋城| 九寨沟县| 比如县| 密山市| 锦州市| 灵山县| 麻阳| 河西区| 绥化市| 武夷山市| 吉林市| 彰化市| 格尔木市| 顺义区| 拉孜县| 凤台县| 黄陵县| 神木县| 都匀市| 武清区| 金塔县|