Android平台上可以使用 Simple API for XML (SAX), Document Object Model(DOM) 和Android 附带的pull解析器 解析XML文件

成都创新互联公司自2013年创立以来,先为天心等服务建站,天心等地企业,进行企业商务咨询服务。为天心企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
众所周知,,DOM解析方式很耗内存, 优先使用SAX或者pull
SAX:
解析速度快,占用内存少,采用事件驱动,即不需要加载完整个文档,而是按内容顺序解析文档,在此过程中,其会判断当前读到的内容是否符合XML语法定义,如果符合就会触发事件,所谓事件,其实就是一些callback方法,具体方法含义比较简单, 看文档即可,定义在DefaultHandler接口中(SAX已内置到JDK5.0中)
待解析xml文件musics.xml:
黑色幽默 Jay 2000 爱在西元前 范特西 2001 回到过去 八度空间 2002 东风破 叶惠美 2003 七里香 七里香 2004 一路向北 十一月的萧邦 2005 
实体类MusicEntity就不贴了,四个属性,上面的xml中也可以看出.
实现了DefaultHandler接口的SaxHandler:
- public class SaxHandler extends DefaultHandler{
 - private static final String TAG = "lanyan";
 - private List
 musics; - private MusicEntity music;
 - //缓存上一次的标签名
 - private String preTag;
 - @Override
 - public void startDocument() throws SAXException {
 - musics = new ArrayList
 (); - }
 - @Override
 - public void startElement(String uri, String localName, String qName,
 - Attributes attributes) throws SAXException {
 - if ("music".equals(localName)) {
 - music = new MusicEntity();
 - music.setId(Integer.parseInt(attributes.getValue("id")));
 - }
 - preTag = localName;
 - }
 - /**
 - * 解析到文档中字符内容时调用
 - * 所以一般网络中传输的xml,其父节点与子节点之间是紧挨在一起的,基本上就是一行,看起来很混乱,其实是为了避免解析时无必要的调用
 - * 这里仅是测试,故忽略这个因素
 - */
 - @Override
 - public void characters(char[] ch, int start, int length)
 - throws SAXException {
 - if (null != music) {
 - String str = new String(ch, start, length);
 - if ("name".equals(preTag)) {
 - music.setName(str);
 - } else if ("albumName".equals(preTag)) {
 - music.setAlbumName(str);
 - } else if ("year".equals(preTag)) {
 - music.setYear(Integer.parseInt(str));
 - }
 - }
 - }
 - @Override
 - public void endElement(String uri, String localName, String qName)
 - throws SAXException {
 - if ("music".equals(localName) && null != music) {
 - musics.add(music);
 - music = null;
 - }
 - preTag = null;
 - }
 - @Override
 - public void endDocument() throws SAXException {
 - }
 - public List
 getMusics() { - return musics;
 - }
 - }
 
对外提供SAX解析服务的接口SaxService:
- public class SaxService {
 - public static List
 readXml(InputStream is) throws Exception { - SAXParserFactory saxFactory = SAXParserFactory.newInstance();
 - SAXParser parser = saxFactory.newSAXParser();
 - // parser.setProperty("http://xml.org/sax/features/namespaces", true);
 - SaxHandler handler = new SaxHandler();
 - parser.parse(is, handler);
 - return handler.getMusics();
 - }
 - }
 
测试方法:
- public void testSaxRead() {
 - InputStream is = XmlPaserTest.class.getClassLoader().getResourceAsStream("musics.xml");
 - try {
 - List
 musics = SaxService.readXml(is); - for (MusicEntity music : musics) {
 - Log.i("lanyan", music.toString());
 - }
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 
Pull:
同样是事件驱动,不同的是不需要实现什么handler接口,标签之间value的读取也不需要通过类似characters(...)的回调方法,相关API已经封转好了
对外提供PULL解析服务的接口PullService中的xml解析方法:
- public static List
 readXml(InputStream is) throws Exception { - List
 musics = null; - XmlPullParser parser = Xml.newPullParser();
 - parser.setInput(is, "UTF-8");
 - int eventCode = parser.getEventType();// 事件类型
 - MusicEntity music = null;
 - while (eventCode != XmlPullParser.END_DOCUMENT) {
 - switch (eventCode) {
 - case XmlPullParser.START_DOCUMENT:// 开始文档事件
 - musics = new ArrayList
 (); - break;
 - case XmlPullParser.START_TAG:// 元素开始标志
 - if ("music".equals(parser.getName())) {
 - music = new MusicEntity();
 - music.setId(new Integer(parser.getAttributeValue(0)));
 - } else if (music != null) {
 - if ("name".equals(parser.getName())) {
 - music.setName(parser.nextText());// 拿到标签后***个文本节点的value
 - } else if ("albumName".equals(parser.getName())) {
 - music.setAlbumName(parser.nextText());
 - } else if ("year".equals(parser.getName())) {
 - music.setYear(Integer.parseInt(parser.nextText()));
 - }
 - }
 - break;
 - case XmlPullParser.END_TAG://元素结束标志
 - if ("music".equals(parser.getName()) && music != null) {
 - musics.add(music);
 - music = null;
 - }
 - break;
 - }
 - eventCode = parser.next();
 - }
 - return musics;
 - }
 
使用PULL解析方式生成xml文件:
PullService中的xml生成方法:
- /**
 - * Pull生成xml数据
 - * @param persons
 - * @param writer
 - * @throws Exception
 - */
 - public static void writeXml(List
 musics, Writer writer) - throws Exception {
 - XmlSerializer serializer = Xml.newSerializer();
 - serializer.setOutput(writer);
 - serializer.startDocument("UTF-8", true);
 - serializer.startTag(null, "musics");
 - for (MusicEntity music : musics) {
 - serializer.startTag(null, "music");
 - serializer.attribute(null, "id", String.valueOf(music.getId()));
 - serializer.startTag(null, "name");
 - serializer.text(music.getName());
 - serializer.endTag(null, "name");
 - serializer.startTag(null, "albumName");
 - serializer.text(music.getAlbumName());
 - serializer.endTag(null, "albumName");
 - serializer.startTag(null, "year");
 - serializer.text(String.valueOf(music.getYear()));
 - serializer.endTag(null, "year");
 - serializer.endTag(null, "music");
 - }
 - serializer.endTag(null, "musics");
 - serializer.endDocument();
 - writer.flush();
 - writer.close();
 - }
 
测试方法:
- public void testPullWrite() throws Exception {
 - List
 musics = new ArrayList (); - MusicEntity music1 = new MusicEntity();
 - music1.setId(1);
 - music1.setName("七里香");
 - music1.setAlbumName("七里香");
 - music1.setYear(2004);
 - musics.add(music1);
 - MusicEntity music2 = new MusicEntity();
 - music2.setId(1);
 - music2.setName("一路向北");
 - music2.setAlbumName("十一月的萧邦");
 - music2.setYear(2005);
 - musics.add(music2);
 - //写入文件
 - // File file = new File(Environment.getExternalStorageDirectory(), "musics.xml");
 - // BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
 - //以字符串形式输出
 - StringWriter writer = new StringWriter();
 - PullService.writeXml(musics, writer);
 - Log.i("lanyan", writer.toString());
 - }
 
输出结果:
七里香 七里香 2004 一路向北 十一月的萧邦 2005 
Copyright © 2009-2022 www.wtcwzsj.com 青羊区广皓图文设计工作室(个体工商户) 版权所有 蜀ICP备19037934号