Android的xml SAX解析的原理是逐行解析,然后调用相应的函数。
在ContentHandler接口中主要用到的函数有:
解析文档开始 startDocument()解析文档结束 endDocument()解析标签开始 startElement(String uri, String localName, String qName, Attributes atts)解析标签结束 endElement(Stringuri, StringlocalName, String qName)解析标签内容 characters(char[] ch, int start, int length)由于实现接口必须重写所有方法,所以我们选择继承DefaultHandler这个类,DefaultHandler是对ContentHandler接口中所有方法的空实现,就是所谓的适配器模式。首先先看一下我们要解析的testxml.xml<?xml version="1.0" encoding="UTF-8"?><workers> <worker id="AQ01"> <name>Mark</name> <sex>男</sex> <status>经理</status> <address>北京</address> <money>4000</money> </worker> <worker id="AD02"> <name>lucy</name> <sex>女</sex> <status>员工</status> <address>上海</address> <money>1000</money> </worker> <worker id="AD03"> <name>lily</name> <sex>女</sex> <status>员工</status> <address>北京</address> <money>3000</money> </worker></workers>我把testxml.xml放在res/raw/testxml.xml,raw文件夹需要自己建。(不要放在xml目录,因为我只是以字符串的方式读入)//读取res/raw/testxml.xml并转换成字符串InputStream inputStream = getResources().openRawResource(R.raw.testxml);String resultStr = getString(inputStream);System.out.PRintln(resultStr); 这个方法是将输入的InputStream转化成字符串,网上看到的http://blog.csdn.net/barryhappy/article/details/7365271其中inputStreamReader = new InputStreamReader(inputStream, "utf-8");"utf-8"要用自己xml文件的编码/** * 输入一个inputStream返回字符串 */public static String getString(InputStream inputStream) { InputStreamReader inputStreamReader = null; try { inputStreamReader = new InputStreamReader(inputStream, "utf-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } BufferedReader reader = new BufferedReader(inputStreamReader); StringBuffer sb = new StringBuffer(""); String line; try { while ((line = reader.readLine()) != null) { sb.append(line); sb.append("/n"); } } catch (IOException e) { e.printStackTrace(); } return sb.toString();}主Activity的完整代码XMLActivity.java,getString()方法懒得封装了,就直接丢进主代码里面package com.example.xml;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.StringReader;import java.io.UnsupportedEncodingException;import javax.xml.parsers.SAXParserFactory;public class XMLActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //读取res/raw/.xml并转换成字符串 InputStream inputStream = getResources().openRawResource(R.raw.testxml); String resultStr = getString(inputStream); System.out.println(resultStr); try { SAXParserFactory factory = SAXParserFactory.newInstance(); XMLReader reader = factory.newSAXParser().getXMLReader(); reader.setContentHandler(new MyContentHandler()); reader.parse(new InputSource(new StringReader(resultStr))); } catch (Exception e) { e.printStackTrace(); } } /** * 输入一个inputStream返回字符串 */ public static String getString(InputStream inputStream) { InputStreamReader inputStreamReader = null; try { inputStreamReader = new InputStreamReader(inputStream, "utf-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } BufferedReader reader = new BufferedReader(inputStreamReader); StringBuffer sb = new StringBuffer(""); String line; try { while ((line = reader.readLine()) != null) { sb.append(line); sb.append("/n"); } } catch (IOException e) { e.printStackTrace(); } return sb.toString(); }}下面是看mars的视频教学打的MyContentHandler.javapackage com.example.xml;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class MyContentHandler extends DefaultHandler { String hisname, address, money, sex, status; String tagName; int i=0; boolean flag; @Override public void startDocument() throws SAXException { System.out.println("``````````begin``````````"); } @Override public void endDocument() throws SAXException { System.out.println("``````````end``````````"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { flag = true; tagName = localName; if(localName.equals("worker")) { for(int i=0; i<attributes.getLength(); i++) { System.out.println(attributes.getLocalName(i) + "=" + attributes.getValue(i)); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { flag = false; if(localName.equals("worker")) { this.printout(); } } private void printout() { System.out.print("name: "); System.out.println(hisname); System.out.print("sex: "); System.out.println(sex); System.out.print("status: "); System.out.println(status); System.out.print("address: "); System.out.println(address); System.out.print("money: "); System.out.println(money); System.out.println(); } /** * characters并不是只执行一次,只有在startElement和endElement之间的那一次才是正确的 * 所以设置一个flag */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //System.out.println(i++); if(flag) { if (tagName.equals("name")) hisname = new String(ch, start, length); else if (tagName.equals("sex")) sex = new String(ch, start, length); else if (tagName.equals("status")) status = new String(ch, start, length); else if (tagName.equals("address")) address = new String(ch, start, length); else if (tagName.equals("money")) money = new String(ch, start, length); } }}这里主要是characters()这个方法并不是在解析每个标签中只执行一次,是个坑,在一个标签解析结束执行endElement后,和在下一个标签解析开始之前,如果碰到"/t"、"/n"之类的characters()也会执行,
视频教学并没有提到。
找了好久才找到一片文章提到这个问题,原文http://blog.csdn.net/feng88724/article/details/7013675
我的解决方法是,既然在startElement和endElement之间执行的characters()获取的数据才是正确的,
那么设个flag,来控制characters()往变量赋值。
新闻热点
疑难解答