Android 支持JAVA传统的两种方式:DOM 和SAX。
DOM 需要load整个文件,所以需要比较多的内存,担正因为此,整颗树都生成好,比较直观。
DOM的代码稍微复杂些,以下是几个准则:
· 整个文档是一个文档节点
· 每个 XML 标签是一个元素节点(element)
· 包含在 XML 元素中的文本是文本节点(text)
· 每一个 XML 属性是一个属性节点 (attribute)
· 注释属于注释节点
关键是得到一个Document对象,并得到对应的层层Node。(element、attribute、textnode都是node。其中element是比较直观理解的元素)。
SAX 的优点是选择性的parse 某个节点,比较方便。
关键是自己实现一个org.xml.sax.helpers.DefaultHandler的基础类,并重载:
startDocument 打开一个文档的callback
endDocument 关闭一个文档的callback
startElement 打开一个元素的callback
endElement 关闭一个元素的callback
characters 读到一个元素的内容的callback (注:这里没有什么文本节点的概念了,只有元素的概念)
在这个函数里面,可以选择性的读取某些元素的内容
例子:
<?xml version="1.0"?>
<books>
<book category="computer-programming">
<author>Steven Haines</author>
<title>Java 2 Primer Plus</title>
<price>44.95</price>
</book>
<book category="fiction">
<author>Tim LaHaye</author>
<title>Left Behind</title>
<price>15.95</price>
</book>
</books>
两种方法的parse:
DOM:
String parseXMLDom(String filename)
{
String result = null;
String temp;
try
{
File file = new File( "/sdcard/book.xml" );
if( !file.exists() )
{
String st = String.format( "Couldn't find file..." );
return st;
}
// Parse the document
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse( file );
// Walk the document
Element root = document.getDocumentElement();
temp =( "root=" + root.getTagName()+"/n" );
result += temp;
// List the children of <books>; a set of <book> elements
NodeList list = root.getChildNodes();
for( int i=0; i<list.getLength(); i++ )
{
Node node = list.item( i );
if( node.getNodeType() == Node.ELEMENT_NODE )
{
// Found a <book> element
temp = ( "Handling node: " +
node.getNodeName()+"/n" );
result += temp;
Element element = ( Element )node;
temp = ( "tCategory Attribute: " +
element.getAttribute( "category" )+"/n" );
result += temp;
// Get its children: <author>, <title>, <price>
NodeList childList = element.getChildNodes();
for( int j=0; j<childList.getLength(); j++ )
{
// Once one of these nodes is attained, the next
// step is locating its text element
// It is important. It is NOT <author>'s value, but it is its text element's value
Node childNode = childList.item( j );
if( childNode.getNodeType() == childNode.ELEMENT_NODE )
{
NodeList childNodeList =
childNode.getChildNodes();
for( int k=0; k<childNodeList.getLength(); k++ )
{
Node innerChildNode = childNodeList.item( k );
temp = ( "ttNode (" + childNode.getNodeName()+ ") = "+
innerChildNode.getNodeValue() +"/n");
result += temp;
//innerChildNode's name is "text", and childNode's value is null
}
}
}
}
}
} catch( Exception e )
{
e.printStackTrace();
}
return result;
}
SAX:
String parseSAX(String filename)
{
String result = "";
File file = new File( "/sdcard/book.xml" );
if( !file.exists() )
{
String st = String.format( "Couldn't find file..." );
return st;
}
FileInputStream read;
try {
read = new FileInputStream(file);
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(read));
/* Parsing has finished. */
result = myExampleHandler.getParsedData();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public class ExampleHandler extends DefaultHandler {
String result = "";
int index = -1;
String category[] = new String [2];
String author[] = new String [2];
String title[] = new String [2];
String price[] = new String [2];
private boolean bbook = false;
private boolean bprice = false;
private boolean bauthor = false;
private boolean btitle = false;
public String getParsedData() {
return this.result;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if(bbook && bprice)
price[index] = new String(ch, start, length)+ "/n";
if(bbook && bauthor)
author[index] = new String(ch, start, length)+ "/n";
if(bbook && btitle)
title[index] = new String(ch, start, length)+ "/n";
super.characters(ch, start, length);
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
int i;
for(i=0; i<=index; i++){
result += "Book: /n";
result += title[i];
result += category[i];
result += author[i];
result += price[i];
}
super.endDocument();
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equals("book")) {
bbook = false;
} else if (localName.equals("author")){
bauthor = false;
}else if (localName.equals("title")){
btitle = false;
}else if (localName.equals("price")){
bprice = false;
}
super.endElement(uri, localName, name);
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
index = -1;
super.startDocument();
}
@Override
public void startElement(String uri, String localName, String name,
Attributes atts) throws SAXException {
// TODO Auto-generated method stub
if (localName.equals("book")) {
bbook = true;
index ++;
String attrValue = atts.getValue("category");
category[index]= attrValue + "/n";
} else if (localName.equals("author")){
bauthor = true;
}else if (localName.equals("title")){
btitle = true;
}else if (localName.equals("price")){
bprice = true;
}
super.startElement(uri, localName, name, atts);
}
}