淺談Android Studio 解析XML的三種方法
一丶概述
文件解析要求,json解析和xml解析,前面文章說過Json轉(zhuǎn)實體類,這里就說說解析XML
內(nèi)容:
Android Studio 解析XML常見的三種方式:DOM PULL SAX (實現(xiàn)XML轉(zhuǎn)實體類并打印輸出)
效果演示:

二丶正文
SAX(Simple API for XML) 使用流式處理的方式,它并不記錄所讀內(nèi)容的相關(guān)信息。它是一種以事件為驅(qū)動的XML API,解析速度快,占用內(nèi)存少。使用回調(diào)函數(shù)來實現(xiàn)。 缺點是不能倒退。
DOM(Document Object Model) 是一種用于XML文檔的對象模型,可用于直接訪問XML文檔的各個部分。它是一次性全部將內(nèi)容加載在內(nèi)存中,生成一個樹狀結(jié)構(gòu),它沒有涉及回調(diào)和復(fù)雜的狀態(tài)管理。 缺點是加載大文檔時效率低下。
Pull內(nèi)置于Android系統(tǒng)中。也是官方解析布局文件所使用的方式。Pull與SAX有點類似,都提供了類似的事件,如開始元素和結(jié)束元素。不同的是,SAX的事件驅(qū)動是回調(diào)相應(yīng)方法,需要提供回調(diào)的方法,而后在SAX內(nèi)部自動調(diào)用相應(yīng)的方法。而Pull解析器并沒有強(qiáng)制要求提供觸發(fā)的方法。因為他觸發(fā)的事件不是一個方法,而是一個數(shù)字。它使用方便,效率高。
SAX、DOM、Pull的比較:
1. 內(nèi)存占用:SAX、Pull比DOM要好;
2. 編程方式:SAX采用事件驅(qū)動,在相應(yīng)事件觸發(fā)的時候,會調(diào)用用戶編好的方法,也即每解析一類XML,就要編寫一個新的適合該類XML的處理類。DOM是W3C的規(guī)范,Pull簡潔。
3. 訪問與修改:SAX采用流式解析,DOM隨機(jī)訪問。
4. 訪問方式:SAX,Pull解析的方式是同步的,DOM逐字逐句
這里不做詳細(xì)講解,看注釋,上代碼
看項目文件,注意XML放的位置,不會建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();
//將解析樹放入內(nèi)存,通過返回值Document來描述結(jié)果
Document document = builder.parse(inputStream);
//取得根元素<personos>
Element root = document.getDocumentElement();
//取得所有person節(jié)點集合
NodeList personNodes = root.getElementsByTagName("person");
for (int i = 0; i < personNodes.getLength(); i++) {
Person person = new Person();
//取得person節(jié)點元素
Element personElement = (Element) personNodes.item(i);
//取得屬性值并設(shè)置ID
person.setId(Integer.parseInt(personElement.getAttribute("id")));
//獲取person的子節(jié)點
NodeList personChilds = personElement.getChildNodes();
for (int j = 0; j < personChilds.getLength(); j++) {
//判斷當(dāng)前節(jié)點是否是元素類型的節(jié)點
if (personChilds.item(j).getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) personChilds.item(j);
if ("name".equals(childElement.getNodeName())) {
//獲取孫節(jié)點的值
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://開始文檔事件
persons = new ArrayList<>();
break;
case XmlPullParser.START_TAG://開始元素事件
//獲取解析器當(dā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)前指向元素的下一個文本節(jié)點的值
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)入下一個元素并觸發(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)前解析到了那個元素節(jié)點名稱
private Person person;
public List<Person> getPersons(){
return persons;
}
//一開始會執(zhí)行這個方法,所以在這里面完成初始化
@Override
public void startDocument() throws SAXException {
persons = new ArrayList<>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//判斷元素節(jié)點是否等于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é)點的數(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開發(fā)主流是傳json,而XML解析一般跟網(wǎng)絡(luò)請求,爬蟲數(shù)據(jù)相關(guān)。當(dāng)然兩者也是可以相互轉(zhuǎn)換的,Java只強(qiáng)大在于提供了很多的類和方法。只要你愿意學(xué),方法總是有的
源碼下載歡迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android音樂播放器制作 掃描本地音樂顯示在手機(jī)(一)
這篇文章主要介紹了Android音樂播放器的制作方法,掃描本地音樂顯示在手機(jī)上,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Android巧用DecorView實現(xiàn)對話框功能
本篇文章主要介紹了Android巧用DecorView實現(xiàn)對話框功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
Android中TextView動態(tài)設(shè)置縮進(jìn)距離的方法
項目需求如果在項目中第一行文字需要添加布局的情況我們應(yīng)該怎么做呢,經(jīng)過一番考慮和查找我最終選擇了縮進(jìn)的方式解決這個問題,這篇文章主要給大家介紹了關(guān)于Android中TextView動態(tài)設(shè)置縮進(jìn)距離的相關(guān)資料,需要的朋友可以參考下2022-04-04
Android自定義ViewGroup實現(xiàn)豎向引導(dǎo)界面
這篇文章主要為大家詳細(xì)介紹了Andoird自定義ViewGroup實現(xiàn)豎向引導(dǎo)界面,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-03-03
Android LayoutInflater深入分析及應(yīng)用
這篇文章主要介紹了Android LayoutInflater分析的相關(guān)資料,需要的朋友可以參考下2017-02-02
Android通話默認(rèn)打開揚(yáng)聲器的方法
這篇文章主要介紹了Android通話默認(rèn)打開揚(yáng)聲器的方法.小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08

