`

XML的解析与生成

    博客分类:
  • 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:

复制代码
public class SaxHandler extends DefaultHandler{
    
    private static final String TAG = "lanyan";
    
    private List<MusicEntity> musics;
    
    private MusicEntity music;
    //缓存上一次的标签名
    private String preTag;
    
    @Override
    public void startDocument() throws SAXException {
        musics = new ArrayList<MusicEntity>();
    }
    
    @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<MusicEntity> getMusics() {
        return musics;
    }
    
}
复制代码

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

复制代码
public class SaxService {
    
    public static 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();
    }
    
}
复制代码

测试方法:

复制代码
public void 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解析方法:

复制代码
public static 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)));
                } 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<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();
    }
复制代码

 测试方法:

复制代码
public void 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>
分享到:
评论

相关推荐

    XML解析与生成

    总结来说,XML解析与生成是软件开发中常用的数据处理技术。理解DOM、SAX和StAX的优缺点以及如何使用它们,对于处理XML数据至关重要。SAX解析器如`SaxXml`实例,展示了如何通过事件驱动的方式高效地处理XML文档,而...

    XML解析与生成工具

    总之,这个"XML解析与生成工具"旨在简化XML处理任务,无论是在数据交换、配置管理还是其他XML应用场景中,都能提供便利。通过阅读README并实践提供的示例,开发者可以快速上手,将XML操作整合到自己的项目中,提高...

    XML解析和生成工具

    本文将深入探讨XML解析和生成工具的相关知识,以及如何利用提供的`Markup.cpp`和`Markup.h`文件进行操作。 XML的结构: XML文档由一系列元素构成,每个元素都有一个开始标签和结束标签,如 `&lt;tag&gt;` 和 `&lt;/tag&gt;`。...

    Android提高第七篇之XML解析与生成.doc

    总之,Android中的XML解析和生成是开发者经常需要掌握的技能。SAX解析器适用于处理大型XML文件,因为它不占用过多内存,而`XmlSerializer`则用于将数据结构转换成XML字符串,方便数据的保存和传输。理解并熟练运用...

    android 解析XML文件 生成XML文件

    在Android开发中,XML文件广泛用于存储数据、配置文件以及应用...以上是Android环境中XML解析与生成的基础知识,实际应用中可能需要根据需求进行扩展和优化。XMLdemo项目应包含了这些方法的完整实现,可供学习和参考。

    android解析生成xml文件

    综上所述,"android解析生成xml文件"这一主题涵盖了XML的基本概念、Android中的XML应用、XML解析与生成的方法,以及可能涉及到的工具和自定义工具类的使用。如果想深入了解Android开发中的XML处理,阅读这篇博客会是...

    JAVA 解析XML生成XML文档实例

    JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

    java XML解析方式实现自动生成word文档

    以下是一个基本的步骤,展示如何使用Java和Apache POI通过XML解析生成Word文档: 1. 引入Apache POI库:在项目中添加Apache POI依赖,通常是通过Maven或Gradle的配置完成。 2. 创建Word文档对象:使用`...

    ios应用源码之对xml文件的解析与导出数据存储在xml中(代码)xmlparser 2018127

    XML(eXtensible Markup Language)是一种...理解并熟练运用XML解析是iOS开发者必备的技能之一,这对于处理从服务器获取的或本地存储的数据至关重要。通过深入学习和实践,开发者能够更高效地管理和操作XML格式的数据。

    android xml多种解析生成

    Android XML 多种解析生成 Android 平台中,XML 文件解析和生成是非常重要的一部分。XML 文件可以存储和交换结构化数据,广泛应用于 Android 应用程序中。本文将介绍 Android 中使用多种解析和生成 XML 文件的方法...

    Pull解析与生成Xml

    我们将讲解如何使用Pull解析器读取本地XML文件,并生成一个新的、格式不同的XML文件。 Pull解析是一种事件驱动的解析方法,它不像DOM解析那样将整个XML文档加载到内存中,而是按需逐个处理XML元素。这种方法节省了...

    XML解析代码

    本压缩包提供了XML解析与生成的四种方式的代码示例,这些都是Android Studio项目中的常见操作。 1. DOM解析 DOM(Document Object Model)是XML的一种树型结构表示,通过加载整个XML文档到内存,可以方便地访问和...

    21天学习android开发教程之XML解析与生成

    本教程主要讲解如何在21天内学习Android开发中的XML解析与生成技术,特别是使用SAX解析器进行高效处理。 XML解析有两种主要方法:SAX(Simple API for XML)和DOM(Document Object Model)。DOM解析器将整个XML...

    使用Pull解析器读取XML文件和生成XML文件

    本篇文章将深入探讨如何使用Pull解析器来读取XML文件,以及如何生成XML文件。Pull解析器是一种轻量级的解析方式,它允许程序在解析XML时按需获取数据,而不需要一次性加载整个文档到内存,从而提高了效率和资源利用...

    基于Python实现的自动化生成XML解析类

    本项目是基于Python实现的自动化XML解析类,它简化了Qt应用中处理XML的流程,避免了手动编写解析逻辑的繁琐工作。 首先,我们来了解XML的基本结构。XML文档由一系列元素构成,每个元素由标签(Tag)、属性...

    Android网络下的XML解析和生成

    在实际应用中,根据需求和性能考虑,开发者可以选择合适的XML解析和生成方法。了解这些基本概念和代码示例,有助于我们在Android网络编程中更好地处理XML数据。在学习过程中,可以参考`XML_Parser`这个压缩包中的...

    XML生成和解析

    ### XML生成和解析 #### 一、概述 随着信息技术的发展,XML(Extensible Markup Language,可扩展标记语言)因其良好的跨平台性和数据可扩展性,成为了一种广泛使用的数据交换格式。XML允许开发者自定义标签,非常...

Global site tag (gtag.js) - Google Analytics