淺談Android Studio 解析XML的三種方法
一丶概述
文件解析要求,json解析和xml解析,前面文章說(shuō)過(guò)Json轉(zhuǎn)實(shí)體類(lèi),這里就說(shuō)說(shuō)解析XML
內(nèi)容:
Android Studio 解析XML常見(jiàn)的三種方式:DOM PULL SAX (實(shí)現(xiàn)XML轉(zhuǎn)實(shí)體類(lèi)并打印輸出)
效果演示:
二丶正文
SAX(Simple API for XML) 使用流式處理的方式,它并不記錄所讀內(nèi)容的相關(guān)信息。它是一種以事件為驅(qū)動(dòng)的XML API,解析速度快,占用內(nèi)存少。使用回調(diào)函數(shù)來(lái)實(shí)現(xiàn)。 缺點(diǎn)是不能倒退。
DOM(Document Object Model) 是一種用于XML文檔的對(duì)象模型,可用于直接訪問(wèn)XML文檔的各個(gè)部分。它是一次性全部將內(nèi)容加載在內(nèi)存中,生成一個(gè)樹(shù)狀結(jié)構(gòu),它沒(méi)有涉及回調(diào)和復(fù)雜的狀態(tài)管理。 缺點(diǎn)是加載大文檔時(shí)效率低下。
Pull內(nèi)置于Android系統(tǒng)中。也是官方解析布局文件所使用的方式。Pull與SAX有點(diǎn)類(lèi)似,都提供了類(lèi)似的事件,如開(kāi)始元素和結(jié)束元素。不同的是,SAX的事件驅(qū)動(dòng)是回調(diào)相應(yīng)方法,需要提供回調(diào)的方法,而后在SAX內(nèi)部自動(dòng)調(diào)用相應(yīng)的方法。而Pull解析器并沒(méi)有強(qiáng)制要求提供觸發(fā)的方法。因?yàn)樗|發(fā)的事件不是一個(gè)方法,而是一個(gè)數(shù)字。它使用方便,效率高。
SAX、DOM、Pull的比較:
1. 內(nèi)存占用:SAX、Pull比DOM要好;
2. 編程方式:SAX采用事件驅(qū)動(dòng),在相應(yīng)事件觸發(fā)的時(shí)候,會(huì)調(diào)用用戶(hù)編好的方法,也即每解析一類(lèi)XML,就要編寫(xiě)一個(gè)新的適合該類(lèi)XML的處理類(lèi)。DOM是W3C的規(guī)范,Pull簡(jiǎn)潔。
3. 訪問(wèn)與修改:SAX采用流式解析,DOM隨機(jī)訪問(wèn)。
4. 訪問(wèn)方式:SAX,Pull解析的方式是同步的,DOM逐字逐句
這里不做詳細(xì)講解,看注釋?zhuān)洗a
看項(xiàng)目文件,注意XML放的位置,不會(huì)建assets參考http://www.dbjr.com.cn/article/144766.htm
XML
<?xml version="1.0" encoding="UTF-8" ?> <persons> <person id="23"> <name>李雷</name> <age>30</age> </person> <person id="20"> <name>韓梅梅</name> <age>25</age> </person> </persons>
person.Java
public class Person { Integer id; String name; Short age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Short getAge() { return age; } public void setAge(Short age) { this.age = age; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
XMLtoEntityActivity
public class XMLtoEntityActivity extends AppCompatActivity { private TextView tv_show_entity; private String string = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.xmlto_entity_activity); tv_show_entity = (TextView) findViewById(R.id.tv_show_entity); } public void startXML(View view){ // SAXService saxService = new SAXService(); // DOMService domService = new DOMService(); PULLService pullService = new PULLService(); try { InputStream inputStream = getAssets().open("Users.xml"); // List<Person> persons = saxService.getPerson(inputStream); // List<Person> persons = domService.getPersons(inputStream); List<Person> persons = pullService.getPersons(inputStream); for (Person person : persons) { Log.e("TAG",person.toString()); string += person.toString(); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } tv_show_entity.setText(string); } }
DOM方法
/** * 采用DOM解析XML內(nèi)容 */ public class DOMService { public List<Person> getPersons(InputStream inputStream) throws Exception { List<Person> persons = new ArrayList<>(); //獲取DOM解析器工廠 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //獲DOM解析器 DocumentBuilder builder = factory.newDocumentBuilder(); //將解析樹(shù)放入內(nèi)存,通過(guò)返回值Document來(lái)描述結(jié)果 Document document = builder.parse(inputStream); //取得根元素<personos> Element root = document.getDocumentElement(); //取得所有person節(jié)點(diǎn)集合 NodeList personNodes = root.getElementsByTagName("person"); for (int i = 0; i < personNodes.getLength(); i++) { Person person = new Person(); //取得person節(jié)點(diǎn)元素 Element personElement = (Element) personNodes.item(i); //取得屬性值并設(shè)置ID person.setId(Integer.parseInt(personElement.getAttribute("id"))); //獲取person的子節(jié)點(diǎn) NodeList personChilds = personElement.getChildNodes(); for (int j = 0; j < personChilds.getLength(); j++) { //判斷當(dāng)前節(jié)點(diǎn)是否是元素類(lèi)型的節(jié)點(diǎn) if (personChilds.item(j).getNodeType() == Node.ELEMENT_NODE) { Element childElement = (Element) personChilds.item(j); if ("name".equals(childElement.getNodeName())) { //獲取孫節(jié)點(diǎn)的值 person.setName(childElement.getFirstChild().getNodeValue()); } else if ("age".equals(childElement.getNodeName())) { person.setAge(Short.parseShort(childElement.getFirstChild().getNodeValue())); } } } persons.add(person); } return persons; } }
PULL方法
/** * 采用PULL解析XML內(nèi)容 */ public class PULLService { public List<Person> getPersons(InputStream inputStream) throws Exception { List<Person> persons = null; Person person = null; //得到PULL解析器 XmlPullParser parser = Xml.newPullParser(); parser.setInput(inputStream,"UTF-8"); //產(chǎn)生事件 int eventType = parser.getEventType(); //如果不是文檔結(jié)束事件就循環(huán)推進(jìn) while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT://開(kāi)始文檔事件 persons = new ArrayList<>(); break; case XmlPullParser.START_TAG://開(kāi)始元素事件 //獲取解析器當(dāng)前指向的元素的名稱(chēng) String name = parser.getName(); if ("person".equals(name)) { person = new Person(); person.setId(Integer.parseInt(parser.getAttributeValue(0))); } if (person != null) { if ("name".equals(name)) { //獲取解析器當(dāng)前指向元素的下一個(gè)文本節(jié)點(diǎn)的值 person.setName(parser.nextText()); } if ("age".equals(name)) { person.setAge(Short.parseShort(parser.nextText())); } } break; case XmlPullParser.END_TAG://結(jié)束元素事件 //判斷是都是person的結(jié)束事件 if ("person".equals(parser.getName())) { persons.add(person); person = null; } break; } //進(jìn)入下一個(gè)元素并觸發(fā)相應(yīng)的事件 eventType = parser.next(); } return persons; } }
SAX方法
/** * 采用SAX解析XML內(nèi)容 */ public class SAXService { public List<Person> getPerson(InputStream inputStream) throws Exception { //得到SAX解析工廠 SAXParserFactory factory = SAXParserFactory.newInstance(); //得到SAX解析器 SAXParser parser = factory.newSAXParser(); PersonParser personParser = new PersonParser(); parser.parse(inputStream,personParser); inputStream.close(); return personParser.getPersons(); } private final class PersonParser extends DefaultHandler { private List<Person> persons = null; private String tag = null;//記錄當(dāng)前解析到了那個(gè)元素節(jié)點(diǎn)名稱(chēng) private Person person; public List<Person> getPersons(){ return persons; } //一開(kāi)始會(huì)執(zhí)行這個(gè)方法,所以在這里面完成初始化 @Override public void startDocument() throws SAXException { persons = new ArrayList<>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //判斷元素節(jié)點(diǎn)是否等于person if ("person".equals(localName)) { person = new Person(); //獲取數(shù)據(jù),參數(shù)為索引下標(biāo) person.setId(Integer.parseInt(attributes.getValue(0))); } tag = localName; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("person".equals(localName)) { persons.add(person); person = null; } tag = null; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (tag != null) { //獲取文本節(jié)點(diǎn)的數(shù)據(jù) String data = new String(ch, start, length); if ("name".equals(tag)) { person.setName(data); } else if ("age".equals(tag)) { person.setAge(Short.parseShort(data)); } } } } }
總結(jié):Android開(kāi)發(fā)主流是傳json,而XML解析一般跟網(wǎng)絡(luò)請(qǐng)求,爬蟲(chóng)數(shù)據(jù)相關(guān)。當(dāng)然兩者也是可以相互轉(zhuǎn)換的,Java只強(qiáng)大在于提供了很多的類(lèi)和方法。只要你愿意學(xué),方法總是有的
源碼下載歡迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android?XML數(shù)據(jù)解析要點(diǎn)介紹
- Android中的xml解析介紹
- Android實(shí)現(xiàn)向本地寫(xiě)入一個(gè)XML文件和解析XML文件
- Android解析XML文件升級(jí)APK的方法
- Android中對(duì)xml文件解析的3種方式總結(jié)
- Android開(kāi)發(fā)中解析xml文件XmlUtils工具類(lèi)與用法示例
- Android編程簡(jiǎn)易實(shí)現(xiàn)XML解析的方法詳解
- Android xml解析實(shí)例詳解
- Android開(kāi)發(fā)筆記XML數(shù)據(jù)解析方法及優(yōu)缺點(diǎn)
相關(guān)文章
Android 三種延遲操作的實(shí)現(xiàn)方法
這篇文章主要介紹了Android 延遲操作的實(shí)現(xiàn)方法的相關(guān)資料,這里提供了三種實(shí)現(xiàn)方法,希望能幫助到大家,需要的朋友可以參考下2017-08-08Android音樂(lè)播放器制作 掃描本地音樂(lè)顯示在手機(jī)(一)
這篇文章主要介紹了Android音樂(lè)播放器的制作方法,掃描本地音樂(lè)顯示在手機(jī)上,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android巧用DecorView實(shí)現(xiàn)對(duì)話框功能
本篇文章主要介紹了Android巧用DecorView實(shí)現(xiàn)對(duì)話框功能,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04Android中TextView動(dòng)態(tài)設(shè)置縮進(jìn)距離的方法
項(xiàng)目需求如果在項(xiàng)目中第一行文字需要添加布局的情況我們應(yīng)該怎么做呢,經(jīng)過(guò)一番考慮和查找我最終選擇了縮進(jìn)的方式解決這個(gè)問(wèn)題,這篇文章主要給大家介紹了關(guān)于Android中TextView動(dòng)態(tài)設(shè)置縮進(jìn)距離的相關(guān)資料,需要的朋友可以參考下2022-04-04Android自定義ViewGroup實(shí)現(xiàn)豎向引導(dǎo)界面
這篇文章主要為大家詳細(xì)介紹了Andoird自定義ViewGroup實(shí)現(xiàn)豎向引導(dǎo)界面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03Android LayoutInflater深入分析及應(yīng)用
這篇文章主要介紹了Android LayoutInflater分析的相關(guān)資料,需要的朋友可以參考下2017-02-02Android通話默認(rèn)打開(kāi)揚(yáng)聲器的方法
這篇文章主要介紹了Android通話默認(rèn)打開(kāi)揚(yáng)聲器的方法.小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08