[Android]Android XML解析
Android除了可以與SQLite作連線外,其實也可透過XML解析的方式,
使Android可以與電腦資料庫進行連線,這篇文章主要是說明Android該如何解析XML,
並且主要不是說明程式碼用途,而是說明該怎樣修改道自己可以使用的情況!!
而使用的範圍當然不止僅限於與資料庫連線,使用的用途可以相當多元的。
首先我們必須要有一個XML格式,而如果是要連線資料庫,那就是在資料庫伺服器中建立一網頁伺服器,
而將資料庫查詢結果透過XML方式來呈現,至於網頁撰寫方式在這邊就不贅述。
下列為一XML檔,後續程式將會以該檔案為範例撰寫。
切記,如果是要以"檔案"方式存取XML,而不是網頁伺服器存取時,
必須將XML檔放至src資料夾底下。
檔案名稱:AllLocation.xml
<AllLocation>
<Location>
<Name>A</Name>
<Upper_left_x>120.123</Upper_left_x>
<Upper_left_y>22.123</Upper_left_y>
<Lower_left>121.123</Lower_left>
<Upper_right>23.123</Upper_right>
</Location>
<Location>
<Name>B</Name>
<Upper_left_x>120.321</Upper_left_x>
<Upper_left_y>22.321</Upper_left_y>
<Lower_left>119.321</Lower_left>
<Upper_right>21.321</Upper_right>
</Location>
</AllLocation>
格式內容可以依照個人需求來修改,後續也會說明其他可修改或對應的地方,
其中我使用的標籤會影響以下的程式碼,如有自行定義的要更正。
接下來是說明該如何宣告用來接收解析後結果的變數名稱,
檔案名稱:Locate.java
package coordinate.location;
public class Locate {
public String Name; //以下變數名稱,建議與XML定義的標籤名稱相同
public String Upper_left_x;
public String Upper_left_y;
public String Lower_left;
public String Upper_right;
public Locate(){}
public Locate(String Name, String Upper_left_x,String Upper_left_y, String Lower_left, String Upper_right)
{
this.Name=Name;
this.Upper_left_x=Upper_left_x;
this.Upper_left_y=Upper_left_y;
this.Lower_left=Lower_left;
this.Upper_right=Upper_right;
}
//以下宣告為兩兩一組,個別宣告變數存取或讀取時使用
//宣告要使用Name內容時使用,建議getName <<其中的文字與變數名稱相同較好管理
public String getName() {
return Name;
}
//宣告要存取Name內容時使用,建議setName <<其中的文字與變數名稱相同較好管理
public void setName(String Name) {
this.Name = Name;
}
public String getUpper_left_x() {
return Upper_left_x;
}
public void setUpper_left_x(String Upper_left_x) {
this.Upper_left_x = Upper_left_x;
}
public String getUpper_left_y() {
return Upper_left_y;
}
public void setUpper_left_y(String Upper_left_y) {
this.Upper_left_y = Upper_left_y;
}
public String getLower_left() {
return Lower_left;
}
public void setLower_left(String Lower_left) {
this.Lower_left = Lower_left;
}
public String getUpper_right() {
return Upper_right;
}
public void setUpper_right(String Upper_right) {
this.Upper_right = Upper_right;
}
}
以上內容如果有自行定義的名稱,其實透過搜尋就可以簡單發現需修改哪邊,
因為變數名稱我都與XML定義的標籤同名,所以相對較好修改,對後續使用也方便。
設定完後,我們該設定一個說明文件,用來告知解析器我們標籤中的文字與我們宣告的變數,
畢竟只是我們自己知道名稱是相同,而解析器還是得告知他該如何對應,並且將值放入變數中。
檔案名稱:SAXContentHandler.java
package coordinate.location;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXContentHandler extends DefaultHandler {
private List<Locate> Locate_List;//修改為自己定義的一個陣列大小,通常除List字眼外,我會與下方變數同名稱
private Locate Locate;//修改為自己訂一個名稱,我整個專案都會統一名稱
private String preTag; //固定不需修改
//getLBSs()名稱可自行定義,但下個檔案中會用到,所以需要注意要對應
public List<Locate> getLBSs() {
return Locate_List;
}
/**
* 接收文件的開始
*/
@Override
public void startDocument() throws SAXException {
Locate_List = new ArrayList<Locate>();//這邊就是與上面宣告的第一個相同
}
/**
* 接收字元資料的通知
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
String data = new String(ch, start, length);//不需修改
//這邊的意思是,當解析到XML中有Name時,就將該標籤的內容存入setName中
if ("Name".equals(preTag)) {
Locate.setName(data);
}
if ("Upper_left_x".equals(preTag)) {
Locate.setUpper_left_x(data);
}
if ("Upper_left_y".equals(preTag)) {
Locate.setUpper_left_y(data);
}
if ("Lower_left".equals(preTag)) {
Locate.setLower_left(data);
}
if ("Upper_right".equals(preTag)) {
Locate.setUpper_right(data);
}
} catch (Exception ee) {
}
}
/**
* 接收元素開始的通知
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
//這邊的意思是,當解析到XML中的Location標籤時,為一筆資料開始
if ("Location".equals(localName)) {
Locate = new Locate();
}
preTag = localName;
}
/**
* 接收元素結尾的通知
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
//這邊的意思是,當解析到XML中的Location標籤時,為一筆資料結束
if ("Location".equals(localName) && Locate != null) {
Locate_List.add(Locate);
Locate = null;
}
preTag = null;
}
}
上面程式碼中,期時會發現許多重複的字,如果要修改為自己定義的名稱或標籤,
很簡單,用搜尋慢慢取代就好。
接下來,就是要如何將XML丟進去解析器解析了,
檔案名稱:SAXParseXML.java
package coordinate.location;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXParseXML {//這的檔案基本上只需要修改下方 List<Locate>,改為自己定義的,如上述檔案中的內容
public static List<Locate> readXML(InputStream inStream) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParse = factory.newSAXParser();
SAXContentHandler handler = new SAXContentHandler();
saxParse.parse(inStream, handler);
inStream.close();
//下方getLBSs()如有自行定義,可修改為上個檔案所修改的名稱
return handler.getLBSs();
}
}
最後,就是Activity程式碼中該如何將所想要的XML丟進去,並且取值出來。
檔案名稱:LocationActivity.java
package coordinate.location;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
//這邊宣告就略過,太站畫面了,撰寫中只需按下Ctrl+Shift+O就會自動帶入了
public class LocationActivity extends Activity {
/** Called when the activity is first created. */
Locate Locate;//名稱為先前自行定義的名稱
List<Locate> Locate_List;
String Name, Upper_left_x, Upper_left_y, Lower_left, Upper_right,Name_ID = "A";
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Locate_List = getXMLData(); //將XML丟入解析器進行解析
ShowXMLData(); //顯示解析後結果
}
private List<Locate> getXMLData() {
List<Locate> Locate_List = new ArrayList<Locate>();//如有修改為其他名稱需要注意的地方!!
try {
//以下為"XML是一個檔案時"將XML丟入解析器的寫法
InputStream inStream = LocationActivity.class.getClassLoader()
.getResourceAsStream("AllLocation.xml");
//以下為"XML來源是網頁伺服器時"將XML丟入解析器的寫法
URL xmlurl = new URL("http://xxx.xxx.xxx.xxx/xml.aspx?ID=x"); //網址依照自己的伺服器名稱,ID只是參考用變數名稱
InputStream inStream = xmlurl.openStream();
//將上方所選擇之XML丟入解析器
Locate_List = SAXParseXML.readXML(inStream);
} catch (Exception ee) {
}
return Locate_List; //如有自行定義必須要修改的地方!!
}
private void ShowXMLData() {
//在解析完成後的內容會以陣列方式丟入Locate_List中,並且比數為第0筆開始
//下方為從第0筆開始存取到最後一筆的範例,並且其中的if是當Name的值為為上方宣告的Name_ID相同時,就存取該筆資料
for (int i = 0; i < Locate_List.size(); i++) {
if (Locate_List.get(i).Name.equals(Name_ID)) {
Name = Locate_List.get(i).Name;
Upper_left_x = Locate_List.get(i).Upper_left_x;
Upper_left_y = Locate_List.get(i).Upper_left_y;
Lower_left = Locate_List.get(i).Lower_left;
Upper_right = Locate_List.get(i).Upper_right;
}
}
}
}
上面的程式碼中,大多的變數我都統一,因為這樣才方便管理以及修改,
並且如是初學者要使用該XML解析器,也可以很方便的修改幾個地方就可使用。
以上有錯字深感抱歉....