android平台上解析xml的常见的工具有三种:dom,sax,pull。
第一种是DOM,
它的特点是一次全部加载,如果对于数据量小的情况下,它的效率还可以,如果XML文件很大的情况下,速度就会慢起来。
第二种方式SAX:
SAX是基于事件驱动的。当然android的事件机制是基于回调函数的,在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。
第三种方式PULL:
这种方式也是基于事件驱动 的,与SAX方式一样,只不过PULL方式读xml回调方法返回的是数字。
下面分别使用它们解析xml文件。
在assert下放置persons.xml文件:
<?xml version="1.0" encoding="utf-8"?> <persons> <person id="1"> <name>张三</name> <age>12</age> </person> <person id="2"> <name>李四</name> <age>14</age> </person> <person id="3"> <name>王五</name> <age>15</age> </person> </persons>
创建Activity文件准备处理文件并显示:
import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.res.AssetManager; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ListView; import android.widget.SimpleAdapter; public class XMLActivity extends Activity implements OnClickListener{ /** Called when the activity is first created. */ private Button btn_dom; private Button btn_sax; private Button btn_pull; private ListView listview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } private void init(){ btn_dom=(Button) findViewById(R.id.dom); btn_sax=(Button) findViewById(R.id.sax); btn_pull =(Button) findViewById(R.id.pull); listview =(ListView) findViewById(R.id.list); btn_dom.setOnClickListener(this); btn_sax.setOnClickListener(this); btn_pull.setOnClickListener(this); } public void onClick(View v) { // TODO Auto-generated method stub int id = v.getId(); List<Person> list = null; InputStream is = null; AssetManager manager = getAssets(); try { //读取xml文件。 is = manager.open("persons.xml"); } catch (IOException e) { e.printStackTrace(); } switch (id) { case R.id.dom: //使用dom解析 try { list = new DomParseService().getPersonsByParseXml(is); showUI(list); } catch (Exception e) { e.printStackTrace(); } break; case R.id.sax: //使用sax解析 try { list = new SAXParseService().getPersonsByParseXml(is); showUI(list); } catch (Exception e) { e.printStackTrace(); } break; case R.id.pull: //使用pull解析 try { list = new PullParseService().getPersonsByParseXml(is); showUI(list); } catch (Exception e) { e.printStackTrace(); } break; default: break; } try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void showUI(List<Person> list) { List<Map<String, Object>> data = new ArrayList<Map<String, Object>>(); for (Person p : list) { Map<String, Object> map = new HashMap<String, Object>(); map.put("id", p.getId()); map.put("name", p.getName()); map.put("age", p.getAge()); data.add(map); } String[] from = { "id", "name", "age" }; int[] to = { R.id.tv_id, R.id.tv_name, R.id.tv_age }; SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.person_list_item, from, to); listview.setAdapter(adapter); } }
创建解析xml文件的接口:
import java.io.InputStream; import java.util.List; public interface IXmlParseService { public List<Person> getPersonsByParseXml(InputStream is) throws Exception; }
dom解析:
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import android.util.Log; public class DomParseService implements IXmlParseService { public List<Person> getPersonsByParseXml(InputStream is) throws Exception { // TODO Auto-generated method stub List<Person> list = null; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder build =factory.newDocumentBuilder(); Document document = build.parse(is); Element rootElement = document.getDocumentElement(); NodeList nodeList = rootElement.getElementsByTagName("person"); if(nodeList==null||nodeList.getLength()==0) { return null; } list = new ArrayList<Person>(); for(int i=0;i<nodeList.getLength();i++) { Person person = new Person(); Element element = (Element) nodeList.item(i); // 得到根节点属性:id int id = Integer.parseInt(element.getAttribute("id")); person.setId(id); /*得到子节点*/ NodeList childnodes = element.getChildNodes(); for(int j=0; j<childnodes.getLength(); j++ ){ Node childNode = (Node)childnodes.item(j); if(childNode.getNodeType() == Node.ELEMENT_NODE){ Element childElement = (Element)childNode; if("name".equals(childElement.getNodeName())){ person.setName(childElement.getFirstChild().getNodeValue()); } else if("age".equals(childElement.getNodeName())){ person.setAge(new Short(childElement.getFirstChild().getNodeValue())); } } } list.add(person); } return list; } }
sax解析:
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.os.Handler; import android.util.Log; public class SAXParseService implements IXmlParseService { public List<Person> getPersonsByParseXml(InputStream is) throws Exception { // TODO Auto-generated method stub SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser =factory.newSAXParser(); MyHandler handler = new MyHandler(); parser.parse(is,handler); return handler.getList(); } private class MyHandler extends DefaultHandler { private List<Person> list; private Person person; private String currentTag; private List<Person> getList() { return list; } @Override public void startDocument() throws SAXException { list = new ArrayList<Person>(); } @Override public void endDocument() throws SAXException { super.endDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if("person".equals(qName)) { person =new Person(); person.setId(Integer.parseInt(attributes.getValue("id"))); }else if("name".equals(qName)||"age".equals(qName)){ currentTag =qName; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String s =new String(ch,start,length); if("name".equals(currentTag)) { person.setName(s); }else if("age".equals(currentTag)) { person.setAge(Integer.parseInt(s)); } currentTag =null; } @Override public void endElement(String uri, String localName, String qName) { if("person".equals(qName)) { list.add(person); person = null; } } } }
pull解析:
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import android.util.Xml; public class PullParseService implements IXmlParseService { public List<Person> getPersonsByParseXml(InputStream is) throws Exception { // TODO Auto-generated method stub List<Person> persons=null; Person person=null; XmlPullParser parser=Xml.newPullParser(); parser.setInput(is, "UTF-8"); int event=parser.getEventType(); while(event!= XmlPullParser.END_DOCUMENT){ switch(event){ case XmlPullParser.START_DOCUMENT: persons=new ArrayList<Person>(); break; case XmlPullParser.START_TAG: if("person".equals(parser.getName())){ Integer personId=new Integer(parser.getAttributeValue(0)); person=new Person(); person.setId(personId); }else if("name".equals(parser.getName())){ String personName=parser.nextText(); person.setName(personName); }else if("age".equals(parser.getName())) person.setAge(new Short(parser.nextText())); break; case XmlPullParser.END_TAG: if("person".equals(parser.getName())){ persons.add(person); person=null; } break; } event=parser.next(); } return persons; } }
运行效果如下: