一个简单用到的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Account>
<username age="27">mingjava</username>
<email>eric.zhan@263.net</email>
<company>j2medev</company>
</Account>
</root>
ParseMIDlet是javax.microedition.midlet.MIDlet的子类。程序启动后,ParseMIDlet从document.xml读取内容并显示在Form上。注意这一步并不解析document.xml。ParseMIDlet的源码如下:
package com.j2medev.chapter10;
import java.io.InputStream;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class ParseMIDlet extends MIDlet implements CommandListener,Runnable{
private Display display = null;
private Form form = null;
private Thread thread = null;
private Command parseCommand = new Command("parse",Command.OK,1);
protected void startApp() throws MIDletStateChangeException {
if(display == null){
display = Display.getDisplay(this);
form = new Form("jaxp");
//把document.xml的原始内容显示在Form上
InputStream is = getClass().getResourceAsStream("/document.xml");
try {
byte[] data = new byte[is.available()];
is.read(data);
form.append(new String(data));
//正确显示出来才添加parseCommand
form.addCommand(parseCommand);
} catch (Exception e) {
e.printStackTrace();
form.append(e.getMessage());
}
form.addCommand(new Command("exit",Command.EXIT,1));
form.setCommandListener(this);
}
display.setCurrent(form);
}
public void commandAction(Command cmd,Displayable d){
if(cmd.getCommandType() == Command.EXIT){
try {
destroyApp(false);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
notifyDestroyed();
}else if(cmd == parseCommand){
//开始解析,在单独的线程中完成
thread = new Thread(this);
thread.start();
}
}
public void run(){
form.deleteAll();
form.append("parsing the xml file");
//创建SAXParserFactory实例
SAXParserFactory instance = SAXParserFactory.newInstance();
try {
//创建SAXParser
SAXParser parser = instance.newSAXParser();
InputStream is = getClass().getResourceAsStream("/document.xml");
//开始解析
parser.parse(is,new MyHandler(form));
} catch (Exception e) {
e.printStackTrace();
}
form.removeCommand(parseCommand);
display.setCurrent(form);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
}
为了避免堵塞用户界面,这里在单独的线程中解析document.xml文件。首先需要创建一个SAXParseFactory对象,SAXParseFactory允许我们配置和创建一个基于SAX的解析器.
SAXParseFactory instance SAXParseFactory.newInstance();
获得SAXParseFactory对象后即可调用它的newParse()方法创建一个SAXParse 解析器。创建了SAXParse对象后,就可以从InputStream中解析XML了,开始解析时DefaultHandler中的相关方法会按照顺序调用。本例中的MyHandler类时DefaultHandler的子类,底层的解析工作就是由它完成的。
MyHandler类:
真正的解析工作都是在MyHandler类中完成的,MyHandler包含一个form成员变量,目的是把解析到的内容直接显示在Form中。
SAXParse是基于事件模型的,顺序解析XML文件。例如,解析到文档开头部分时,startDocument()方法会被调用;解析到文件的末尾时,endDocument()方法会被调用。类似的,当开始解析一个XML元素时,startElement()方法会被调用;解析某个元素结束时,endElement()方法会被调用。关于DefaultHandler的方法定义请参考JSR172的java文档。
package com.j2medev.chapter10;
import javax.microedition.lcdui.Form;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyHandler extends DefaultHandler{
private Form form = null;
public MyHandler(Form _form) {
form = _form;
form.deleteAll();
}
public void startDocument() throws SAXException {
System.out.println("startDocument");
}
public void characters(char[] ch, int start, int length) throws SAXException {
if(length != 0)
form.append(new String(ch,start,length));
System.out.println("characters");
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//读取username|email|company字段的值
int num=0;
if(qName.equals("username") || qName.equals("email")||qName.equals("company")){
form.append(qName);
//判断属性是否为空
int len = attributes.getLength();
if(len != 0){
for(int i = 0;i<len;i++){
form.append("("+attributes.getQName(i)+attributes.getValue(i)+")");
}
}
form.append(":");
}
num = num+1;
System.out.println("num=:"+num);
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("username") || qName.equals("email")||qName.equals("company")){
form.append("/n");
}
System.out.println("endElement");
}
public void endDocument() throws SAXException {
}
}
运行ParseMIDlet 解析document.xml文件的结果如下图:
参考:《Java ME核心技术与最佳实践》