xml使用

解析

将要解析的数据

<persons>
	<person id="1">
		<name>zhangsan</name>
		<age>22</age>
	</person>
	<person id="2">
		<name>wanger</name>
		<age>24</age>
	</person>
	<person id="3">
		<name>lisi</name>
		<age>26</age>
	</person>
	<person id="4">
		<name>zhaoliu</name>
		<age>28</age>
	</person>
</persons>

PULL 解析

// 类似 SAX解析,基于事件流,允许主动从解析器中获取事件,可主动结束解析(跳出 while)

/**
 * 1. 通过解析器工厂获取 PULL 解析器:
 * 2. 设置 XML 文件的编码格式
 * 3. 获取当前事件类型:返回为整型值
 * 4. while 循环判断事件类型:END_DOCUMENT、START_TAG、END_TAG
 * 5. 获取当前结点名:getName();获取下一节点文本:nextText()
 * 6. 注意最后将指针移至下一节点,并返回该节点的事件类型 next()
 * 
 * PS 事件类型主要有五个:
 * START_DOCUMENT: XML 头文件的事件类型
 * END_DOCUMENT:   XML 文件尾的事件类型
 * START_TAG:      开始节点的事件类型
 * END_TAG:        结束节点的事件类型
 * TEXT:           文本节点的事件类型
 */
 
private List<Person> pullParseXML(String result) {

    List<Person> persons = null;
    Person person = null;

    try {
        XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
        parser.setInput(new StringReader(result));

        // 当前事件类型
        int eventType = parser.getEventType();

        // 直到文档末尾才停止解析
        while (eventType != XmlPullParser.END_DOCUMENT) {

            switch (eventType) {

                case XmlPullParser.START_DOCUMENT:
                    persons = new ArrayList<>();
                    break;

                case XmlPullParser.START_TAG:
                    if ("person".equals(parser.getName())) {
                        person = new Person();
                        person.setId(parser.getAttributeValue(0));
                    } else if ("name".equals(parser.getName())) {
                        person.setName(parser.nextText());
                    } else if ("age".equals(parser.getName())) {
                        person.setAge(parser.nextText());
                    }
                    break;

                case XmlPullParser.END_TAG:
                    if ("person".equals(parser.getName())) {
                        persons.add(person);
                        person = null;
                    }
                    break;
            }

            // 通过 next() 方法触发下一事件
            eventType = parser.next();
        }
        return persons;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

// 调用方式,下同
List<Person> persons = pullParseXML(HttpTool.doGet("http://10.0.2.2:8080/xml.xml"));

SAX 解析

// 基于事件流,会自动将事件推入事件处理器进行处理,不能控制主动结束解析

/**
 * 1. 通过解析器工厂获取 SAX 解析器
 * 2. 通过 DefaultHandler 处理类解析
 */

private List<Person> saxParseXML(String result) {
    try {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        PersonHandler handler = new PersonHandler();
        parser.parse(new ByteArrayInputStream(result.getBytes()), handler);

		// 处理类返回集合
        return handler.getPersons();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

class PersonHandler extends DefaultHandler {

    private List<Person> persons;
    private Person person;

    @Override
    public void startDocument() throws SAXException {
        persons = new ArrayList<>();
    }

	// 分别记录当前解析到的标签名、值
    private String currentTag, currentValue;
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("person".equals(qName)) {
            person = new Person();

            for (int i = 0; i < attributes.getLength(); i++) {
                if ("id".equals(attributes.getQName(i))) {
                    person.setId(attributes.getValue(i));
                }
            }
        }
		
		// 设置当前标签名
        currentTag = qName;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        currentValue = new String(ch, start, length);
        if (null != currentValue && !TextUtils.isEmpty(currentValue) && !"\n".equals(currentValue)) {
            if ("name".equals(currentTag)) {
                person.setName(currentValue);
            } else if ("age".equals(currentTag)) {
                person.setAge(currentValue);
            }
        }
        currentTag = null;
        currentValue = null;
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("person".equals(qName)) {
            persons.add(person);
            person = null;
        }
    }

    public List<Person> getPersons() {
        return persons;
    }
}

DOM 解析

/** 解析时会将整个文档加载进内存,极占内存资源,不推荐用(移动端) */

private List<Person> domParseXML(String result) {
    try {
        List<Person> persons = new ArrayList<>();

		// 加载文档
        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(result.getBytes()));

		// 根元素节点
        Element documentElement = document.getDocumentElement();

		// 标签为 person 的节点集合
        NodeList nodeList = documentElement.getElementsByTagName("person");
        for (int i = 0; i < nodeList.getLength(); i++) {

            Person person = new Person();

			// 若当前节点是元素
            if (nodeList.item(i).getNodeType() == Document.ELEMENT_NODE) {
                Element personElement = (Element) nodeList.item(i);

				// 元素的属性值
                person.setId(personElement.getAttribute("id"));

				// person 元素下的子元素集
                NodeList childNodeList = personElement.getChildNodes();
                for (int j = 0; j < childNodeList.getLength(); j++) {
                    if (childNodeList.item(j).getNodeType() == Document.ELEMENT_NODE) {
                        if ("name".equals(childNodeList.item(j).getNodeName())) {
                            person.setName(childNodeList.item(j).getFirstChild().getNodeValue());
                        } else if ("age".equals(childNodeList.item(j).getNodeName())) {
                            person.setAge(childNodeList.item(j).getFirstChild().getNodeValue());
                        }
                    }
                }
            }

            persons.add(person);
            person = null;
        }

        return persons;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

这里写图片描述

序列化生成 XML 文档

/** 序列化创建元素或属性 */

XmlSerializer xmlSerializer = Xml.newSerializer();

FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/demo.xml"));

xmlSerializer.setOutput(fos, "UTF-8");

xmlSerializer.startDocument("UTF-8", true);

xmlSerializer.startTag(null, "persons");

    xmlSerializer.startTag(null, "person").attribute(null, "id", "1");
        xmlSerializer.startTag(null, "name").text("zhangsan").endTag(null, "name");
        xmlSerializer.startTag(null, "age").text("27").endTag(null, "age");
    xmlSerializer.endTag(null, "person");

    xmlSerializer.startTag(null, "person").attribute(null, "id", "2");
        xmlSerializer.startTag(null, "name").text("zhaoliu").endTag(null, "name");
        xmlSerializer.startTag(null, "age").text("29").endTag(null, "age");
    xmlSerializer.endTag(null, "person");

    xmlSerializer.startTag(null, "person").attribute(null, "id", "3");
        xmlSerializer.startTag(null, "name").text("wangwu").endTag(null, "name");
        xmlSerializer.startTag(null, "age").text("26").endTag(null, "age");
    xmlSerializer.endTag(null, "person");

    xmlSerializer.startTag(null, "person").attribute(null, "id", "4");
        xmlSerializer.startTag(null, "name").text("lisi").endTag(null, "name");
        xmlSerializer.startTag(null, "age").text("24").endTag(null, "age");
    xmlSerializer.endTag(null, "person");
xmlSerializer.endTag(null, "persons");

xmlSerializer.endDocument();

这里写图片描述

SAX、DOM、PULL比较

  1. sax、pull 占用内存比 dom 少,适合Android开发

  2. sax 基于事件驱动,每解析一类xml就需要创建新的对应的处理类

    dom 遵循 W3C 规范,广为熟知和运用

    pull 简洁性高

  3. dom 可随机访问xml中任意一个节点,sax 和 pull 采用的是流式解析

  4. sax、pull 解析方式是同步的,即解析器读到哪就对哪里进行处理

    dom 则是逐字逐句进行解析,并先将xml加载进内存全部读完后再操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值