在上篇文章講述了SonyEriCSSon發布了更好支持企業級應用程序開發的新JSR,這其中就包括J2ME Web Service 1.0(JSR 172),索尼愛立信的W600就支持了JSR172。本文講述如何使用JSR 172提供的API來解析xml。
我們知道JSR172是由兩個部分組成的:
1. 一個輕量級的標準XML解析器
2. Web Services的遠程調用API
其中這個JSR172實現的輕量級的XML解析器是JAXP1.2(java API for XML PRocessing)的一個子集。我們可以查看WTK提供的API看到j2me-xml提供的類一共只有12個,這說明這個輕量級的XML解析器是適合在移動電話這種資源受限設備上運行的。
下面我們通過一個例子介紹如何使用JSR 172解析XML,首先我們需要準備一個XML文件放在項目當中,內容如下:
值得注意的是當XML文件中包含漢字的時候,我們應該使用文本工具,比如notepad或者Ultral Edit等把它轉換成UTF-8編碼文件,否則解析的結果將包含亂碼。
為了保存XML文件中的信息,我們構造一個普通的Java類Phone,它包含兩個成員變量分別對應name和colour,代碼如下所示:
/*
* Phone.java
*
* Created on 2005年8月6日, 下午9:40
*
* To change this template, choose Tools Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
/**
*
* @author Administrator
*/
public class Phone {
private String colour = "";
private String name = "";
/** Creates a new instance of Phone */
public Phone() {
}
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在JSR 172中實現的是SAX模式的解析器,它和DOM模式的不同在于,SAX解析器按照順序解析文件并不保存其內容,而DOM解析器則是首先把XML文件解析后存儲在一個對象樹中,可見DOM模式更加耗費內存資源。能夠解析XML之前首先需要創建SAXParser的實例,
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
接下來我們要獲得XML文件的輸入流,并把它作為其中一個參數傳遞給saxParser的parse方法,
InputStream is = this.getClass().getResourceAsStream("phone.xml");
saxParser.parse(is,new BasicHandler(this));
那么SAXParser是如何解析xml文件的呢?DefaultHandler是SAX2默認的事件處理器基類,用于處理XML解析事件的方法如下:
startDocument()
startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes)
characters(char[] ch, int start, int length)
endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)
endDocument()
默認情況下,DefaultHandler的上述方法什么也不做,因此我們必須自己擴展DefaultHandler并且覆蓋上述的方法。我們的程序中提供了一個BasicHandler用來處理xml文件。
class BasicHandler extends DefaultHandler
在BasicHandler類中有兩個成員變量
private Vector phones = new Vector();
private Stack tagStack = new Stack();
phones用來存儲我們已經解析出來的Phone對象,tagStack則用來存放我們解析到的元素名稱,比如sonyericsson,phone,name,colour等。在文檔解釋結束后,也就是在endDocument()方法內我們把解析的結果顯示在手機屏幕上,為了讓讀者可以更清楚地明白SAX解析器的解析順序,這里筆者用了一些打印語句來把重要的信息打印出來,BasicHandler的幾個重要方法如下:
public void startDocument() throws SAXException {}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("the qName is "+qName);
if(qName.equals("phone")) {
Phone phone = new Phone();
phones.addElement(phone);
}
tagStack.push(qName);
System.out.println("the tag stack's length is "+tagStack.size());
}
public void characters(char[] ch, int start, int length) throws SAXException {
String chars = new String(ch, start, length).trim();
System.out.println("the character is "+chars);
if(chars.length() > 0) {
String qName = (String)tagStack.peek();
Phone currentPhone = (Phone)phones.lastElement();
if (qName.equals("name")) {
currentPhone.setName(chars);
} else if(qName.equals("colour")) {
currentPhone.setColour(chars);
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("the end qName is "+qName);
tagStack.pop();
}
public void endDocument() throws SAXException {
StringBuffer result = new StringBuffer();
for (int i=0; i
result.append(currentPhone.getName() + " 是 " + currentPhone.getColour() + "/n");
}
helloXML.alert(result.toString());
}
從這里下載源代碼
總結:本文講述了如何使用JSR 172提供的輕量級XML解析器來解析XML,并給出了具體的代碼。下篇文章我們將一起學習一下如何使用Web Services的遠程調用API。
(出處:http://www.49028c.com)
新聞熱點
疑難解答