文章目錄
- 1.XML資料決議
- 1.1 要點介紹
- 1.1.1 XML格式資料的簡單理解
- 1.1.2 三種決議XML方法
- 1.1.2.1 SAX決議XML
- 1.1.2.2 DOM決議XML
- 1.1.2.3 pull決議XML
- 2.Json資料決議
- 2.1 Json概念以及與XML的比較
- 2.2 Json的格式規范
- 2.3 Json決議類
- 2.4 案例演示
- 2.4.1 新建專案
- 2.4.2 添加背景圖片
- 2.4.3 activity_main.xml
- 2.4.4 創建資訊檔案
- 2.4.5 strings.xml
- 2.4.6 MainActivity.java
- 2.4.7 啟動程式,查看效果
1.XML資料決議
1.1 要點介紹
1.1.1 XML格式資料的簡單理解
XML資料全名叫做可拓展標記語言,類似于HTML,在很多時候我們將xml用來儲存資料,可以將其看作一個微型的資料庫,比如我們Android中的SharedPreference就是使用XML檔案來保存配置資訊的,而我們的SQLite的底層也是一個xml檔案;而在網路應用方面通常作為資訊的載體,我們通常把資料包裝成xml來傳遞,
1.1.2 三種決議XML方法
1.1.2.1 SAX決議XML
對檔案進行順序掃描,當掃描到檔案(document)開始與結束,元素(element)開始與結束,檔案(document)結束等地方時,通知事件處理函式,由事件處理函式做相應動作,然后繼續同樣的掃描,直至檔案結束,決議速度快,占用記憶體也較少,每需要決議一類xml就需要撰寫新的適合該類XML的處理類,
可供重寫的方法:

核心代碼:
SAX決議類:SaxHelper.java:
public class SaxHelper extends DefaultHandler {
private Person person;
private ArrayList<Person> persons;
//當前決議的元素標簽
private String tagName = null;
/**
* 當讀取到檔案開始標志是觸發,通常在這里完成一些初始化操作
*/
@Override
public void startDocument() throws SAXException {
this.persons = new ArrayList<Person>();
Log.i("SAX", "讀取到檔案頭,開始決議xml");
}
/**
* 讀到一個開始標簽時呼叫,第二個引數為標簽名,最后一個引數為屬性陣列
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("person")) {
person = new Person();
person.setId(Integer.parseInt(attributes.getValue("id")));
Log.i("SAX", "開始處理person元素~");
}
this.tagName = localName;
}
/**
* 讀到到內容,第一個引數為字串內容,后面依次為起始位置與長度
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//判斷當前標簽是否有效
if (this.tagName != null) {
String data = new String(ch, start, length);
//讀取標簽中的內容
if (this.tagName.equals("name")) {
this.person.setName(data);
Log.i("SAX", "處理name元素內容");
} else if (this.tagName.equals("age")) {
this.person.setAge(Integer.parseInt(data));
Log.i("SAX", "處理age元素內容");
}
}
}
/**
* 處理元素結束時觸發,這里將物件添加到結合中
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("person")) {
this.persons.add(person);
person = null;
Log.i("SAX", "處理person元素結束~");
}
this.tagName = null;
}
/**
* 讀取到檔案結尾時觸發,
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
Log.i("SAX", "讀取到檔案尾,xml決議結束");
}
//獲取persons集合
public ArrayList<Person> getPersons() {
return persons;
}
}
然后我們在MainActivity.java中寫上如下方法,然后要決議XML的時候呼叫下 就好了~
private ArrayList<Person> readxmlForSAX() throws Exception {
//獲取檔案資源建立輸入流物件
InputStream is = getAssets().open("person1.xml");
//①創建XML決議處理器
SaxHelper ss = new SaxHelper();
//②得到SAX決議工廠
SAXParserFactory factory = SAXParserFactory.newInstance();
//③創建SAX決議器
SAXParser parser = factory.newSAXParser();
//④將xml決議處理器分配給決議器,對檔案進行決議,將事件發送給處理器
parser.parse(is, ss);
is.close();
return ss.getPersons();
}
person1.xml檔案,然后放到assets目錄下的
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id = "11">
<name>SAX決議</name>
<age>18</age>
</person>
<person id = "13">
<name>XML1</name>
<age>43</age>
</person>
</persons>
1.1.2.2 DOM決議XML
先把 XML檔案都讀到記憶體中,然后再有DOM
API來訪問樹形結構并獲取資料,這個寫起來很簡單,但是很消耗記憶體,加入讀取的資料量大,手機記憶體不夠的話可能導致手機死機,不建議在安卓設備中使用決議,簡單的XML檔案到可以,
常用的五個介面與類:Document,Element,Node,NodeList,DOMParser
DOM是整個檔案決議到記憶體中,供用戶需要的節點資訊,支持隨機訪問,
DOM的api:

核心代碼:
DomHelper.java
public class DomHelper {
public static ArrayList<Person> queryXML(Context context)
{
ArrayList<Person> Persons = new ArrayList<Person>();
try {
//①獲得DOM決議器的工廠示例:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//②從Dom工廠中獲得dom決議器
DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
//③把要決議的xml檔案讀入Dom決議器
Document doc = dbBuilder.parse(context.getAssets().open("person2.xml"));
System.out.println("處理該檔案的DomImplemention物件=" + doc.getImplementation());
//④得到檔案中名稱為person的元素的結點串列
NodeList nList = doc.getElementsByTagName("person");
//⑤遍歷該集合,顯示集合中的元素以及子元素的名字
for(int i = 0;i < nList.getLength();i++)
{
//先從Person元素開始決議
Element personElement = (Element) nList.item(i);
Person p = new Person();
p.setId(Integer.valueOf(personElement.getAttribute("id")));
//獲取person下的name和age的Note集合
NodeList childNoList = personElement.getChildNodes();
for(int j = 0;j < childNoList.getLength();j++)
{
Node childNode = childNoList.item(j);
//判斷子note型別是否為元素Note
if(childNode.getNodeType() == Node.ELEMENT_NODE)
{
Element childElement = (Element) childNode;
if("name".equals(childElement.getNodeName()))
p.setName(childElement.getFirstChild().getNodeValue());
else if("age".equals(childElement.getNodeName()))
p.setAge(Integer.valueOf(childElement.getFirstChild().getNodeValue()));
}
}
Persons.add(p);
}
} catch (Exception e) {e.printStackTrace();}
return Persons;
}
}
從代碼我們就可以看出DOM決議XML的流程,先整個檔案讀入Dom決議器,然后形成一棵樹, 然后我們可以遍歷節點串列獲取我們需要的資料!
1.1.2.3 pull決議XML
XML
pull提供了開始元素和結束元素,當某個元素開始時,我們呼叫parser.nextText0從XML檔案中提取所有字符資料,當解釋到一個檔案結束時,自動生成EndDocument,常用介面和類:XmlPullParser,XmlSreializer,XmlPullParserFactory
和sax差不多,代碼沒那么實作較為簡單,非常適合移動設備,安卓系統內置pull決議器,而且安卓系統內部默認使用pull來決議XML檔案,如果需要在Jay2EE或者其他使用pull需要匯入兩個包,后面給出下載,
決議檔案流程:

核心代碼
public static ArrayList<Person> getPersons(InputStream xml)throws Exception
{
//XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance();
ArrayList<Person> persons = null;
Person person = null;
// 創建一個xml決議的工廠
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 獲得xml決議類的參考
XmlPullParser parser = factory.newPullParser();
parser.setInput(xml, "UTF-8");
// 獲得事件的型別
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if ("person".equals(parser.getName())) {
person = new Person();
// 取出屬性值
int id = Integer.parseInt(parser.getAttributeValue(0));
person.setId(id);
} else if ("name".equals(parser.getName())) {
String name = parser.nextText();// 獲取該節點的內容
person.setName(name);
} else if ("age".equals(parser.getName())) {
int age = Integer.parseInt(parser.nextText());
person.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if ("person".equals(parser.getName())) {
persons.add(person);
person = null;
}
break;
}
eventType = parser.next();
}
return persons;
}
使用Pull生成xml資料的流程:

核心代碼:
public static void save(List<Person> persons, OutputStream out) throws Exception {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(out, "UTF-8");
serializer.startDocument("UTF-8", true);
serializer.startTag(null, "persons");
for (Person p : persons) {
serializer.startTag(null, "person");
serializer.attribute(null, "id", p.getId() + "");
serializer.startTag(null, "name");
serializer.text(p.getName());
serializer.endTag(null, "name");
serializer.startTag(null, "age");
serializer.text(p.getAge() + "");
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}
serializer.endTag(null, "persons");
serializer.endDocument();
out.flush();
out.close();
}
2.Json資料決議
JavaScript Object Natation, 一種輕量級的資料交換格式, 與XML一樣, 廣泛被采用的客戶端和服務端互動的解決方案!具有良好的可讀和便于快速撰寫的特性,
2.1 Json概念以及與XML的比較
-
JSON和XML的資料可讀性基本相同;
-
JSON和XML同樣擁有豐富的決議手段
-
JSON相對于XML來講,資料的體積小
-
JSON與JavaScript的互動更加方便
-
JSON對資料的描述性比XML較差
-
JSON的速度要遠遠快于XML
2.2 Json的格式規范
[
{ "id":"1","name":"基神","age":"18" },
{ "id":"2","name":"B神","age":"18" },
{ "id":"3","name":"曹神","age":"18" }
]
2.3 Json決議類
這些API都存在于org.json包下,而我們用到的類有下面這些:
- JSONObject: Json物件,可以完成Json字串與Java物件的相互轉換
- JSONArray: Json陣列,可以完成Json字串與Java集合或物件的相互轉換
- JSONStringer: Json文本構建類,這個類可以幫助快速和便捷的創建JSON text, 每個JSONStringer物體只能對應創建一個JSON text
- JSONTokener:Json決議類
- JSONException:Json例外
2.4 案例演示
2.4.1 新建專案


2.4.2 添加背景圖片

2.4.3 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/btnReadJSON"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doReadJSON"
android:text="@string/read_json"
android:textSize="20sp" />
<Button
android:id="@+id/btnParseJson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doParseJSON"
android:text="@string/parse_json"
android:textSize="20sp" />
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#bbbbbb" />
<ScrollView
android:id="@+id/svContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#0000ff"
android:textSize="20sp" />
</ScrollView>
</LinearLayout>
2.4.4 創建資訊檔案
將視圖切換至project視圖,創建assets目錄,在里面創建textbook.json


將視圖切換回Android視圖,查看textbook.json檔案

[
{
"id": "1",
"name": "計算機基礎教程",
"press": "清華大學出版社",
"author": "李曉云",
"price": "30.5"
},
{
"id": "2",
"name": "Java程式設計",
"press": "水利水電出版社",
"author": "張國鋒",
"price": "40"
},
{
"id": "3",
"name": "安卓應用開發",
"press": "北京大學出版社",
"author": "鄭曉華",
"price": "60.5"
},
{
"id": "4",
"name": "PHP應用開發教程",
"press": "南京大學出版社",
"author": "滕玉國",
"price": "27.5"
}
]
2.4.5 strings.xml

<resources>
<string name="app_name">讀取決議JSON</string>
<string name="read_json">讀取JSON</string>
<string name="parse_json">決議JSON</string>
</resources>
2.4.6 MainActivity.java

package net.nell.readparsejson;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private TextView tvContent; // 顯示內容的標簽
private String content; // 檔案內容字串
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 利用布局檔案設定用戶界面
setContentView(R.layout.activity_main);
// 通過資源標識獲得控制元件實體
tvContent = findViewById(R.id.tvContent);
}
/**
* 讀取JSON
*
* @param view
*/
public void doReadJSON(View view) {
try {
// 讀取assets目錄里的檔案,獲取位元組輸入流
InputStream is = getResources().getAssets().open("textbook.json");
// 獲取位元組輸入流長度
int length = is.available();
// 定義位元組緩沖區
byte[] buffer = new byte[length];
// 讀取位元組輸入流,將資料保存在位元組緩沖區里
is.read(buffer);
// 將位元組緩沖區的資料轉換成字串
content =new String(buffer, "utf-8");
// 將字串顯示在標簽里
tvContent.setText(content);
// 設定標簽的文本顏色
tvContent.setTextColor(Color.BLUE);
// 關閉位元組輸入流
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 決議JSON
*
* @param view
*/
public void doParseJSON(View view) {
// 判斷用戶是否先讀取了JSON
if (content == null) {
Toast.makeText(this, "請先讀取JSON!", Toast.LENGTH_LONG).show();
} else {
try {
// 清空標簽內容
tvContent.setText("");
// 創建Json陣列
JSONArray jsonArray = new JSONArray(content);
// 遍歷Json陣列
for (int i = 0; i < jsonArray.length(); i++) {
// 獲取Json物件
JSONObject jsonObject = jsonArray.getJSONObject(i);
// 對于Json物件按鍵取值
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String press = jsonObject.getString("press");
String author = jsonObject.getString("author");
String price = jsonObject.getString("price");
// 拼接成一個圖書資訊
String book = "編號:" + id + "\n書名:《" + name + "》\n出版社:" + press + "\n作者:" + author + "\n單價:" + price + "\n\n";
// 將圖書資訊添加到標簽里
tvContent.append(book);
// 設定標簽的文本顏色
tvContent.setTextColor(Color.RED);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
2.4.7 啟動程式,查看效果



轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/252157.html
標籤:其他
