XML的解析与生成

XML的解析与生成

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

众所周知,,DOM解析方式很耗内存,优先使用SAX或者pull
SAX:
解析速度快,占用内存少,采用事件驱动,即不需要加载完整个文档,而是按内容顺序解析文档,在此过程中,其会判断当前读到的内容是否符合XML语法定义,如果符合就会触发事件,所谓事件,其实就是一些callback方法,具体方法含义比较简单,看文档即可,定义在DefaultHandler接口中(SAX已内置到JDK5.0中)
待解析xml文件musics.xml:

复制代码

<?xml version="1.0" encoding="utf-8"?><musics><music id="1"><name>黑色幽默</name><albumName>Jay</albumName><year>2000</year></music><music id="2"><name>爱在西元前</name><albumName>范特西</albumName><year>2001</year></music><music id="3"><name>回到过去</name><albumName>八度空间</albumName><year>2002</year></music><music id="4"><name>东风破</name><albumName>叶惠美</albumName><year>2003</year></music><music id="5"><name>七里香</name><albumName>七里香</albumName><year>2004</year></music><music id="6"><name>一路向北</name><albumName>十一月的萧邦</albumName><year>2005</year></music></musics>

复制代码


实体类MusicEntity就不贴了,四个属性,上面的xml中也可以看出.


实现了DefaultHandler接口的SaxHandler:

复制代码

publicclass SaxHandler extends DefaultHandler{    privatestaticfinal String TAG = "lanyan";    private List<MusicEntity> musics;    private MusicEntity music;  //缓存上一次的标签名private String preTag;    @Override  publicvoid startDocument() throws SAXException {    musics = new ArrayList<MusicEntity>();  }    @Override  publicvoid 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  publicvoid 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);      } elseif ("albumName".equals(preTag)) {        music.setAlbumName(str);      } elseif ("year".equals(preTag)) {        music.setYear(Integer.parseInt(str));      }    }      }    @Override  publicvoid endElement(String uri,String qName)      throws SAXException {    if ("music".equals(localName) && null != music) {      musics.add(music);      music = null;    }    preTag = null;  }    @Override  publicvoid endDocument() throws SAXException {  }    public List<MusicEntity> getMusics() {    return musics;  }  }

复制代码

对外提供SAX解析服务的接口SaxService:

复制代码

publicclass SaxService {    publicstatic List<MusicEntity> 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();  }  }

复制代码

测试方法:

复制代码

publicvoid testSaxRead() {        InputStream is = XmlPaserTest.class.getClassLoader().getResourceAsStream("musics.xml");        try {      List<MusicEntity> 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解析方法:

复制代码

publicstatic List<MusicEntity> readXml(InputStream is) throws Exception {    List<MusicEntity> 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<MusicEntity>();        break;      case XmlPullParser.START_TAG:// 元素开始标志if ("music".equals(parser.getName())) {          music = new MusicEntity();          music.setId(new Integer(parser.getAttributeValue(0)));        } elseif (music != null) {          if ("name".equals(parser.getName())) {            music.setName(parser.nextText());// 拿到标签后第一个文本节点的value
                    } elseif ("albumName".equals(parser.getName())) {            music.setAlbumName(parser.nextText());          } elseif ("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   */publicstaticvoid writeXml(List<MusicEntity> 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();  }

复制代码

测试方法:

复制代码

publicvoid testPullWrite() throws Exception {        List<MusicEntity> musics = new ArrayList<MusicEntity>();        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());  }

复制代码

输出结果:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><musics><music id="1"><name>七里香</name><albumName>七里香</albumName><year>2004</year></music><music id="1"><name>一路向北</name><albumName>十一月的萧邦</albumName><year>2005</year></music></musics>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇