xml解析分为三种dom,sax,pull。下面就为大家讲一下pull解析xml
1、Sax解析(simple api for xml)
使用流式处理的方式,它并不记录所读内容的相关信息。它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调函数来实现。
class MyDefaultHander extends DefaultHandler{
private List<Student> list;
private Student student;
@Override
public void startDocument() throws SAXException {
super.startDocument();
list=new ArrayList<>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if(qName.equals("student")){
student=new Student();
}
preTag=qName;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("student")){
list.add(student);
}
preTag=null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(preTag!=null){
if(preTag.equals("id")){
student.setId(Integer.parseInt(new String(ch,start,length)));
}else if(preTag.equals("name")){
student.setName(new String(ch,start,length));
}else if(preTag.equals("age")){
student.setAge(Integer.parseInt(new String(ch,start,length)));
}
}
}
public List<Student> getStudents(){
return list;
}
}
public List<Student> sax_parser(){
List<Student> list=null;
try {
SAXParser parser= SAXParserFactory.newInstance().newSAXParser();
InputStream is= getAssets().open("student.xml");
MyDefaultHander hander=new MyDefaultHander();
parser.parse(is,hander);
list= hander.getStudents();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
2、Dom解析
DOM(Document Object Model) 是一种用于XML文档的对象模型,可用于直接访问XML文档的各个部分。它是一次性全部将内容加载在内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。 缺点是加载大文档时效率低下。
public List<Student> DOM_parser(){
DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
List<Student> list=null;
try {
Document dom= factory.newDocumentBuilder().parse(getAssets().open("student.xml"));
Element element= dom.getDocumentElement();
NodeList nodeList= element.getChildNodes();
list=new ArrayList<>();
for(int i=0;i<nodeList.getLength();i++){
Log.i(TAG, "DOM_parser: "+nodeList.item(i).getNodeName());
if(nodeList.item(i).getNodeName().equals("student")){
NodeList childList= nodeList.item(i).getChildNodes();
Student stu=new Student();
for(int k=0;k<childList.getLength();k++){
if(childList.item(k).getNodeName().equals("id")){
stu.setId(Integer.parseInt(childList.item(k).getFirstChild().getNodeValue()));//注意直接getNodeValue()永远返回null,需调用getFirsetChild()后调用getNodeValue()
}else if(childList.item(k).getNodeName().equals("name")){
stu.setName(childList.item(k).getFirstChild().getNodeValue());
}else if(childList.item(k).getNodeName().equals("age")){
stu.setAge(Integer.parseInt(childList.item(k).getFirstChild().getNodeValue()));
}
}
list.add(stu);
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
return list;
}
3、pull解析(android 推荐)
Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。
public List<Student> Xml_pull_parser(){
List<Student> list=null;
XmlPullParser parser= Xml.newPullParser();
try {
parser.setInput(getAssets().open("student.xml"),"UTF-8");
int event_code= parser.getEventType();
Student student=null;
while (event_code!=XmlPullParser.END_DOCUMENT){
switch (event_code){
case XmlPullParser.START_DOCUMENT:
list=new ArrayList<>();
break;
case XmlPullParser.START_TAG:
if(parser.getName().equals("student")){
student=new Student();
}
if(student!=null){
if(parser.getName().equals("id")){
// Log.i(TAG, "Xml_pull_parser: id="+parser.getText());
student.setId( Integer.parseInt(parser.nextText()));
}else if(parser.getName().equals("name")){
student.setName(parser.nextText());
}else if(parser.getName().equals("age")){
student.setAge(Integer.parseInt(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG:
if(parser.getName().equals("student")){
list.add(student);
student=null;
}
break;
}
event_code= parser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
而且一般我们在做项目的时候就可以根据我们的需求来看那种解析适合自己的项目。 ^-^ …… ^-^