Java XML解析 - 利用DOM4j解析XML

dom4j是一个简单的开源库,用于处理XML、 XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP。dom4j是目前在xml解析方面是最优秀的(Hibernate、Sun的JAXM也都使用dom4j来解析XML),它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。

1. Iterator迭代解析xml

//测试xml文件
<?xml version="1.0" encoding="UTF-8"?>
<students name="zhangsan">
    <hello name="lisi">hello Text1</hello>
    <hello name="lisi2">hello Text2</hello>
    <hello name="lisi3">hello Text3</hello>
    <world name="wangwu">world text1</world>
    <world name="wangwu2">world text2</world>
    <world >world text3</world>
</students>
/**
 * dom4j读取并解析xml
 */
public class Dom4JTest2
{
    public static void main(String[] args) throws Exception
    {
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(new File("students.xml"));

        // 获取根元素
        Element root = document.getRootElement();
        System.out.println("Root: " + root.getName());

        // 获取所有子元素
        List<Element> childList = root.elements();
        System.out.println("total child count: " + childList.size());

        // 获取特定名称的子元素
        List<Element> childList2 = root.elements("hello");
        System.out.println("hello child: " + childList2.size());

        // 获取名字为指定名称的第一个子元素
        Element firstWorldElement = root.element("world");
        // 输出其属性
        System.out.println("first World Attr: "
                + firstWorldElement.attribute(0).getName() + "="
                + firstWorldElement.attributeValue("name"));

        System.out.println("迭代输出-----------------------");
        // 迭代输出
        for (Iterator iter = root.elementIterator(); iter.hasNext();)
        {
            Element e = (Element) iter.next();
            System.out.println(e.attributeValue("name"));

        }

        System.out.println("用DOMReader-----------------------");
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        // 注意要用完整类名
        org.w3c.dom.Document document2 = db.parse(new File("students.xml "));

        DOMReader domReader = new DOMReader();

        // 将JAXP的Document转换为dom4j的Document
        Document document3 = domReader.read(document2);

        Element rootElement = document3.getRootElement();

        System.out.println("Root: " + rootElement.getName());
    }
}

代码运行后输出:

Root: students
total child count: 6
hello child: 3
first World Attr: name=wangwu
迭代输出-----------------------
lisi
lisi2
lisi3
wangwu
wangwu2
null
用DOMReader-----------------------
Root: students

2. 使用xpath解析XML

//studentInfo.xml
<?xml version="1.0" encoding="utf-8"?>
<students> 
  <student age="25">
    <!--如果没有age属性,默认的为20-->  
    <name>崔卫兵</name>  
    <college>PC学院</college>  
    <telephone>62354666</telephone>  
    <notes>男,1982年生,硕士,现就读于北京邮电大学</notes> 
  </student>  
  <student> 
    <name>cwb</name>  
    <college leader="学院领导">PC学院</college>
    <!--如果没有leader属性,默认的为leader-->  
    <telephone>62358888</telephone>  
    <notes>男,1987年生,硕士,现就读于中国农业大学</notes> 
  </student>  
  <student age="45"> 
    <name>xxxxx</name>  
    <college leader="">xxx学院</college>  
    <telephone>66666666</telephone>  
    <notes>注视中,注释中</notes> 
  </student>  
  <student age=""> 
    <name>lxx</name>  
    <college>yyyy学院</college>  
    <telephone>88888888</telephone>  
    <notes>注视中111,注释中222</notes> 
  </student> 
</students>
/**
 * 利用dom4j与XPath进行XML解析
 */
public class Dom4jReadExmple {
    /**
  * 利用XPath操作XML文件,获取指定节点或者属性的值,并放入HashMap中
  * @param filename String 待操作的XML文件(相对路径或者绝对路径)
  * @param hm       HashMap 存放选择的结果,格式:<nodename,nodevalue>或者<nodename+attrname,attrvalue>
  */
    public void getSelectedNodeValue(String filename, HashMap < String, String > hm) {
        try {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new File(filename));
            //获取学生姓名为"崔卫兵"的年龄
            List list = document.selectNodes("/students/student[name=\"崔卫兵\"]/@age");
            Iterator iter = list.iterator();
            if (iter.hasNext()) {
                Attribute attribute = (Attribute) iter.next();
                hm.put("崔卫兵-" + attribute.getName(), attribute.getValue());
            } else {
                hm.put("崔卫兵-age", "20");
            }

            //获取学生姓名为"崔卫兵"的年龄
            list = document.selectNodes("/students/student[name=\"cwb\"]/@age");
            iter = list.iterator();
            if (iter.hasNext()) {
                Attribute attribute = (Attribute) iter.next();
                hm.put("cwb-" + attribute.getName(), attribute.getValue());
            } else {
                hm.put("cwb-age", "20");
            }

            //获取学生姓名为"cwb"所在的学院名称
            list = document.selectNodes("/students/student[name=\"cwb\"]/college");
            iter = list.iterator();
            if (iter.hasNext()) {
                Element element = (Element) iter.next();
                String name = element.getName();
                String value = element.getText();
                hm.put("cwb-" + name, value);
            }

            //获取学生姓名为"cwb"所在学院的领导
            list = document.selectNodes("/students/student[name=\"cwb\"]/college/@leader");
            iter = list.iterator();
            if (iter.hasNext()) {
                Attribute attribute = (Attribute) iter.next();
                hm.put("cwb-college-" + attribute.getName(), attribute.getValue());
            } else {
                hm.put("cwb-college-leader", "leader");
            }

            //获取学生姓名为"lxx"所在的学院名称
            list = document.selectNodes("/students/student[name=\"lxx\"]/college");
            iter = list.iterator();
            if (iter.hasNext()) {
                Element element = (Element) iter.next();
                String name = element.getName();
                String value = element.getText();
                hm.put("lxx-" + name, value);
            }

            //获取学生姓名为"lxx"所在学院的领导
            list = document.selectNodes("/students/student[name=\"lxx\"]/college/@leader");
            iter = list.iterator();
            if (iter.hasNext()) {
                Attribute attribute = (Attribute) iter.next();
                hm.put("lxx-college-" + attribute.getName(), attribute.getValue());
            } else {
                hm.put("lxx-college-leader", "leader");
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
}
/**
 * 测试Dom4jReadExmple解析的情况
 */
public class TestDom4jReadExmple {
 public static void main(String[] args) {
     try{
       //获取解析完后的解析信息
       HashMap<String,String> hashMap;
       Dom4jReadExmple drb=new Dom4jReadExmple();
       //利用XPath操作XML文件,获取想要的属性值
       hashMap = new HashMap<String,String>();
       drb.getSelectedNodeValue("studentInfo.xml", hashMap);
       System.out.println("崔卫兵-age:"+hashMap.get("崔卫兵-age"));
       System.out.println("cwb-age:"+hashMap.get("cwb-age"));
       System.out.println("cwb-college:"+hashMap.get("cwb-college"));
       System.out.println("cwb-college-leader:"+hashMap.get("cwb-college-leader"));
       System.out.println("lxx-college:"+hashMap.get("lxx-college"));
       System.out.println("lxx-college-leader:"+hashMap.get("lxx-college-leader"));
     }catch(Exception ex){
       ex.printStackTrace();
     }
   }
}

运行结果

崔卫兵-age:25
cwbage:20
cwb-college:PC学院
cwb-college-leader:学院领导
lxx-college:yyyy学院
lxx-college-leader:leader 

总结

DOM4j解析XML推荐使用xpath,xpath功能是非常强大的。