Android中解析与创建XML文件

在Android中对XML的操作有多种方式,常见的有三种方式:SAX、DOM和PULL方式。
DOM方式会把整个XML文件加载到内存中,在PC上常使用DOM的方式。
但是在性能敏感的设备上,主要采用的是SAX的方式,但是缺点是嵌套多个分支的时候处理不是很方便。
而PULL的方式类似SAX方式,同样很节省内存。
因此,本文章中只提供PULL的方式解析与创建XML文件。

基础类

本例中使用的实体类的定义如下:

public class CAddress implements Serializable {

    /** IP地址 */
    private String ip;
    /** 端口 */
    private int port;
    /** 地址来源:本地添加或者网络推送 */
    private String source;
    /** 说明:公司内网地址或者外网 **/
    private String description;
    /** 服务器地址隶书公司名称 */
    private String companyName;

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    private static final long serialVersionUID = 1L;

    public CAddress() {
    }
}

XML的创建DEMO

构建数据

首先构建一个数据结构,即XML的数据来源,代码如下:

package com.keyisoftware.toperaxml;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
/**
 * 
 * @author daqin
 *
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            CAddress.write(getAddressList());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /***
     * 构建数据
     * @return
     */
    public static List<CAddress> getAddressList() {

        List<CAddress> addresses = new ArrayList<CAddress>();
        CAddress address = null;


        address = new CAddress();
        address.setIp("192.168.1.234");
        address.setPort(443);
        address.setDescription("说明:内网地址");
        address.setSource("来源:网络推送");
        address.setCompanyName("可依软件有限责任公司");
        addresses.add(address);

        address = new CAddress();
        address.setIp("221.237.152.95");
        address.setPort(443);
        address.setDescription("说明:外网地址");
        address.setSource("来源:本地添加");
        address.setCompanyName("可依调研有限责任公司");
        addresses.add(address);

        address = new CAddress();
        address.setIp("192.168.1.105");
        address.setPort(443);
        address.setDescription("说明:内网测试");
        address.setSource("来源:本地添加");
        address.setCompanyName("可依餐饮有限责任公司");
        addresses.add(address);

        address = new CAddress();
        address.setIp("221.237.152.95");
        address.setPort(8443);
        address.setDescription("说明:外网地址");
        address.setSource("来源:本地添加");
        address.setCompanyName("可依生物制药股份有限公司");
        addresses.add(address);

        address = new CAddress();
        address.setIp("192.168.199.225");
        address.setPort(443);
        address.setDescription("说明:内网地址");
        address.setSource("来源:网络推送");
        address.setCompanyName("大秦集团");
        addresses.add(address);

        return addresses;
    }

}
创建XML文件的关键方法

一般定义在实体类中,或者定义在逻辑层中,具体代码如下:

public static boolean write(List<CAddress> addresses) throws IllegalArgumentException, IllegalStateException, IOException {
        File file = new File("/sdcard/address.xml");
        XmlSerializer serializer = Xml.newSerializer();
        FileOutputStream fos = null;
        // 根据文件对象创建一个文件的输出流对象
        fos = new FileOutputStream(file);
        // 设置输出的流及编码
        serializer.setOutput(fos, "UTF-8");
        // 设置XML的编码格式以及是否独立关联,true默认独立不关联,false反之;
        serializer.startDocument("UTF-8", true);
        // 设置缩进选项
        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
        // 根标签开始
        serializer.startTag(null, "Addresses");

        for (CAddress cAddress : addresses) {
            // 子标签的开始
            serializer.startTag(null, "address");
            // 设置子标签的属性
            serializer.attribute(null, "company", cAddress.getCompanyName());

            // 设置子标签的子标签,可以无限递归循环下去
            serializer.startTag(null, "description");
            serializer.text(cAddress.getDescription());
            serializer.endTag(null, "description");

            serializer.startTag(null, "source");
            serializer.text(cAddress.getSource());
            serializer.endTag(null, "source");

            serializer.startTag(null, "IP");
            serializer.text(cAddress.getIp());
            serializer.endTag(null, "IP");

            serializer.startTag(null, "Port");
            serializer.text("" + cAddress.getPort());
            serializer.endTag(null, "Port");

            serializer.endTag(null, "address");
        }
        serializer.endTag(null, "Addresses");
        serializer.endDocument();

        fos.flush();
        fos.close();
        return true;
    }
创建的XML文件的结果如下
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Addresses>
  <address company="可依软件有限责任公司">
    <description>说明:内网地址</description>
    <source>来源:网络推送</source>
    <IP>192.168.1.234</IP>
    <Port>443</Port>
  </address>
  <address company="可依调研有限责任公司">
    <description>说明:外网地址</description>
    <source>来源:本地添加</source>
    <IP>221.237.152.95</IP>
    <Port>443</Port>
  </address>
  <address company="可依餐饮有限责任公司">
    <description>说明:内网测试</description>
    <source>来源:本地添加</source>
    <IP>192.168.1.105</IP>
    <Port>443</Port>
  </address>
  <address company="可依生物制药股份有限公司">
    <description>说明:外网地址</description>
    <source>来源:本地添加</source>
    <IP>221.237.152.95</IP>
    <Port>8443</Port>
  </address>
  <address company="大秦集团">
    <description>说明:内网地址</description>
    <source>来源:网络推送</source>
    <IP>192.168.199.225</IP>
    <Port>443</Port>
  </address>
</Addresses>

XML的解析DEMO

实现解析的功能函数
public static List<CAddress> parse(InputStream inputStream) {
        List<CAddress> addresses = null;
        CAddress address = null;
        XmlPullParser xmlParser = Xml.newPullParser();
        try {
            xmlParser.setInput(inputStream, "utf-8");
            int envType = xmlParser.getEventType();
            while (envType != XmlPullParser.END_DOCUMENT) {
                String tag = xmlParser.getName();
                switch (envType) {
                case XmlPullParser.START_TAG:
                    if (tag.equalsIgnoreCase("Addresses")) {
                        addresses = new ArrayList<CAddress>();
                    } else if (tag.equalsIgnoreCase("Address")) {
                        address = new CAddress();
                        address.setCompanyName(xmlParser.getAttributeValue(null, "company"));
                    } else {
                        if (address != null) {
                            if (tag.equalsIgnoreCase("description")) {
                                address.setDescription(xmlParser.nextText());
                            }
                            if (tag.equalsIgnoreCase("source")) {
                                address.setSource(xmlParser.nextText());
                            }
                            if (tag.equalsIgnoreCase("IP")) {
                                address.setIp(xmlParser.nextText());
                            }
                            if (tag.equalsIgnoreCase("Port")) {
                                String port = xmlParser.nextText();
                                address.setPort(Integer.parseInt(port));
                            }
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (tag.equalsIgnoreCase("Address")) {
                        addresses.add(address);
                        address = null;
                    }
                    break;
                default:
                    break;
                }
                envType = xmlParser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return addresses;
    }
调用代码如下
File file = new File("/sdcard/address.xml");
        try {
            FileInputStream inputStream = new FileInputStream(file);
            List<CAddress> addresses = CAddress.parse(inputStream);
            System.out.println("CAddress:" + addresses.size());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }