学习安卓sax解析xml时,想用java写一个解析某个xml文件的Handler,代码如下:
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class XMLParse {
public static void main(String[] args){
FileInputStream fis = null;
try {
fis = new FileInputStream("E:\\Apache24\\Apache\\htdocs\\get_data.xml");
parseXMLWithSAX(fis);
}catch (IOException e){
e.printStackTrace();
}finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static void parseXMLWithSAX(InputStream is){
try {
ContentHandler handler = new ContentHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setContentHandler(handler);
reader.parse(new InputSource(is));
}catch (Exception e){
e.printStackTrace();
}
}
}
class ContentHandler extends DefaultHandler{
StringBuilder id;
StringBuilder name;
StringBuilder version;
String nodeName;
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
nodeName = localName;
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if("app".equals(localName)) {
System.out.println("id is " + id.toString().trim());
System.out.println("name is " + name.toString().trim());
System.out.println("version is " + version.toString().trim());
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(nodeName.equals("id")) {
id.append(ch, start, length);
}else if(nodeName.equals("name")){
name.append(ch, start, length);
}else if(nodeName.equals("version")){
version.append(ch, start, length);
}
}
}
具体实现逻辑和在安卓里写的handler差不多,文件也是同一个文件,但是始终没有输出,于是开始调试。首先是打印输入流的内容,和文件一字不差,没毛病。接着打印nodeName,发现nodeName为空字符,很奇怪啊,于是再打印这两个方法中的localName:
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
nodeName = localName;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("app".equals(localName)) {
System.out.println("id is " + id.toString().trim());
System.out.println("name is " + name.toString().trim());
System.out.println("version is " + version.toString().trim());
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
结果始终为空,问题找到。于是查阅资料,发现,这两个方法还有一个qName参数,在java中节点名称是qName,localName为空,安卓则相反!修改代码:
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//nodeName = localName in Android
nodeName = qName;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//"app".equals("localName") in Android
if("app".equals(qName)) {
System.out.println("id is " + id.toString().trim());
System.out.println("name is " + name.toString().trim());
System.out.println("version is " + version.toString().trim());
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
终于成功解析xml!