xml的解析

xml解析思想

数据存储在xml文件中,如果想要将其读取到java内存中,这时就需要对xml进行解析,解析xml有下面两个思想:

  • dom
    dom会将xml文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为对象。
    • 优点:可以对dom树进行增删改查。
    • 缺点:dom树非常占内存,解析速度慢。
  • sax
    逐行读取,基于事件驱动
    • 优点:不占内存,速度快
    • 缺点:只能读取,不能回写

xml常用解析器

  • JAXP:sun公司提供的解析器,支持dom和sax,不过使用的不多。
  • JDOM
  • DOM4J:全称是dom for java,是jdom的升级版,性能优异,使用较为广泛。

这里主要介绍dom4j的使用方式,首先下载dom4j相关的jar包:
http://pan.baidu.com/s/1kVeKBQJ
下载后解压,将里面的dom4j-1.6.1.jar文件拷贝到web项目中的lib文件夹下。
代码示例,这里来读取之前写的book.xml文件:

package com.monkey1024.xml;

import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 * 使用dom4j解析文件
 *
 */
public class Dom4jTest01 {

    /*
     * 得到某个具体的节点内容:第3本书的书名--》java之道
     */
    @Test 
    public void test1() throws DocumentException {
        // 创建一个xml解析对象
        SAXReader reader = new SAXReader();
        // 把xml文档加载到document对象中
        Document document = reader.read("src/book.xml");
        //获取根节点
        Element root = document.getRootElement();
        // 得到当前节点的所有子节点
        List list = root.elements();
        // 得到第三本书对象
        Element thirdBook = (Element) list.get(2);
        // 得到当前节点的文本内容
        String name = thirdBook.element("name").getText();
        System.out.println(name);
    }

    /*
     * // 遍历所有元素节点
     */
    @Test 
    public void test2() throws DocumentException {
        // 创建一个xml解析对象
        SAXReader reader = new SAXReader();
        // 把xml文档加载到document对象中
        Document document = reader.read("src/book.xml");
        Element root = document.getRootElement();
        treeSelect(root);
    }

    //递归
    private void treeSelect(Element ele) {
        // 输出当前节点的名子
        System.out.println(ele.getName());
        // ele.nodeCount()得到当前节点的所有子节点的数量
        for (int i = 0; i < ele.nodeCount(); i++) {
            // 取出下标为i的节点
            Node node = ele.node(i);
            // 判断当前节点是否为标签
            if (node instanceof Element) {
                // 把node强转为标签(Element)
                treeSelect((Element) node);
            } else {
                System.out.println(node.getText());
            }
        }
    }
}

使用xpath方式读取xml
xpath主要用来查找xml中的内容。
常用方法:

selectSingleNode();
selectNodes();

注意:使用时要先将jaxen-1.1-beta-6.jar包导入到项目中。

语法:

nodename 选取此节点。
/     从根节点选取。
//     从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
..     选取当前节点的父节点。
@     选取属性。
[@属性名]    属性过滤
[标签名]     子元素过滤

示例:

package com.monkey1024.xml;

import java.util.List;

import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 * 使用Xpath方式读取文档
 *
 */
public class XpathTest01 {
    @Test
    public void test1() throws Exception{
            SAXReader read = new SAXReader();
            Document document = read.read("src/book.xml");

            Node node1 = document.selectSingleNode("/books/book/name");
            System.out.println(node1.getText());

            Node node2 = document.selectSingleNode("/books/book[4]/name");
            System.out.println(node2.getText());

            Node node3 = document.selectSingleNode("/books/book/attribute::id");
            System.out.println(node3.getText());

            Node node4= document.selectSingleNode("/books/book[3]/attribute::id");
            System.out.println(node4.getText());
    }

    @Test
    public void test2() throws Exception{
        SAXReader read = new SAXReader();
        Document document = read.read("src/book.xml");
        List list = document.selectNodes("//*");
        for (int i = 0; i < list.size(); i++) {
            Node node = (Node)list.get(i);
            System.out.println(node.getName()+"\t"+node.getText());
        }
    }
}