XML解析——Dom4j解析器

目录


dom4j解析器

跳转到目录
一、dom4j基本用法

  • 导入dom4j提供的jar包
    链接:https://pan.baidu.com/s/1yBCg-Jk_G-mT4MIgZwG0yA
    提取码:dt8x
    注意:导入jar包后记得 add to buildpath

  • 获取document

    SAXReader reader = new SAXReader();
    Document document = reader.read(url);

  • document的父接口为Node

    若在document里找不到的方法,可以在Node内找

  • document的常用方法
    getRootElement() 获取根节点,返回为 Element

  • Element是接口,父接口为Node
    getParent() 获取父节点
    addElement 添加标签
    element(qname) 获取标签下面的第一个子标签,arg为标签名称.
    elements(qname) 获取标签下面是这个名称的所有子标签.
    elements() 获取标签下面的所有一层子标签.

二、使用dom4j查询操作
跳转到目录
people.xml

<?xml version="1.0" encoding="utf-8" ?>
<people>
    <p1>
        <name>zhangsan</name>
        <age>20</age>
    </p1>
    <p1>
        <name>lisi</name>
        <age>30</age>
    </p1>
</people>	

查询所有name元素里的值的步骤

  • 创建解析器
  • 获取document
  • 获取根节点 getRootElement() 返回Element
  • 得到所有p1标签
  • 得到name element(“name”)方法
  • 获取name的值 getText()方法
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class TestDom4j {
    public static void main(String[] args) throws Exception {
        selectName();
    }

    // 查询xml中所有name元素的值
    public static void selectName() throws Exception {
        /*
         * 1. 创建解析器
         * 2. 得到document
         * 3. 获取根节点
         * 4. 得到p1
         * 5. 得到p1下面的name
         * 6. 得到name里面的值
         *
         * */
        // 创建解析器
        SAXReader saxReader = new SAXReader();
        // 获取document
        Document document = saxReader.read("12_XML/src/com/sunny/xml/people.xml");
        // 得到根节点
        Element rootElement = document.getRootElement();
        // 得到p1
        List<Element> list = rootElement.elements("p1");
        // 遍历list
        for (Element element : list) {
            // element是每一个p1元素
            // 得到p1下面的name元素
            Element name1 = element.element("name");
            // 得到name里面的值
            String s = name1.getText();
            System.out.println(s);
        }
    }
}

查询获取到的第一个name的值

/*
         * 1. 创建解析器
         * 2. 得到document
         * 3. 获取根节点
         * 4. 得到第一个p1元素
         * 5. 得到p1下面的name元素
         * 6. 得到name元素里面的值
         *
         * */
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("12_XML/src/com/sunny/xml/people.xml");
        Element rootElement = document.getRootElement();
        // 得到第一个p1
        Element p1 = rootElement.element("p1");
        // 得到p1下面的name元素
        Element name1 = p1.element("name");
        System.out.println(name1.getText());
    }

三、使用dom4j添加操作
跳转到目录

在第一个p1标签末尾添加一个sex元素

// 在第一个p1标签末尾添加一个sex元素
    public static void addSex() throws Exception {
        /*
         * 1. 创建解析器
         * 2. 得到document
         * 3. 获取根节点
         * 4. 得到第一个p1元素 element方法
         * 5. 在p1下面添加元素 addElement("标签名称")方法 返回Element
         * 6. 在添加完成后,在元素下面添加文本  setText("文本内容")方法
         * 7. 回写xml
         *      格式化: OutputFormat, 使用createPrettyPrint方法,漂亮格式
         *      使用类XMLWriter, new这个类.
         *          arg1: xml路径,new FileOutputStream("xml路径")
         *          arg2: 格式化对象
         * */
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("12_XML/src/com/sunny/xml/people.xml");
        Element rootElement = document.getRootElement();
        // 得到第一个p1
        Element p1 = rootElement.element("p1");
        // 在p1下面直接添加元素
        Element sex = p1.addElement("sex");
        // 在sex下面添加文本
        sex.setText("nv");
        // 回写xml
        OutputFormat format = OutputFormat.createPrettyPrint();
//        OutputFormat format = OutputFormat.createCompactFormat();
        XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("12_XML/src/com/sunny/xml/people.xml"), format);
        xmlWriter.write(document);
        xmlWriter.close();
    }

在第一个p1标签的age元素前添加school标签

public static void addAgeBeforeSchool() throws Exception{
        /*
         * 1. 创建解析器
         * 2. 得到document
         * 3. 获取根节点
         * 4. 获取到第一个p1
         * 5. 获取p1下面所有的元素
         *      elements()方法,在特定位置添加元素
         *      使用list的add(int index, E element)方法,在特定位置添加元素
         *          - 使用DocumentHelper类方法createElement创建元素
         *          - 把文本添加到标签下面使用setText("文本内容"方法
         * 6. 回写xml
         * */
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("12_XML/src/com/sunny/xml/people.xml");
        Element rootElement = document.getRootElement();
        Element p1 = rootElement.element("p1");
        List list = p1.elements();
        // 创建元素
        Element schoolEle = DocumentHelper.createElement("school");
        // 在school下面添加文本
        schoolEle.setText("coderZYGui");
        // 在特定的位置添加
        list.add(1, schoolEle);
        // 回写xml
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("12_XML/src/com/sunny/xml/people.xml"), format);
        xmlWriter.write(document);
        xmlWriter.close();
    }

抽取Dom4jUtils工具类
跳转到目录

public class Dom4jUtils {

    public static final String PATH = "12_XML/src/com/sunny/xml/people.xml";

    // 返回document
    public static org.dom4j.Document getDocument(String path) {
        try {
            // 创建解析器
            SAXReader saxReader = new SAXReader();
            // 得到document
            Document document = saxReader.read(path);
            return document;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 回写xml方法
    public static void xmlWriters(String path, Document document) {
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), format);
            xmlWriter.write(document);
            xmlWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

优点:

  • 可以提高开发速度,代码可维护性好

四、使用dom4j修改节点的操作
跳转到目录

修改第一个p1下面的age元素的值

  • setText("内容") 给元素设置内容
  • 得到document
  • 获取根节点, 然后在得到第一个p1元素
  • 得到第一个p1下面的age element("age")方法
  • 修改age值 setText("内容")方法
  • 回写xml
    // 修改第一个p1下面的age元素的值
    public static void modifyFirstAge() throws Exception{
        /*
        * 1. 得到document
        * 2. 获取根节点,然后得到第一个p1元素
        * 3. 得到p1下面的age
        * 4. 修改值为99
        * 5. 回写xml
        *
        * */
        // 得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        // 获取根节点
        Element rootElement = document.getRootElement();
        // 得到p1
        Element p1 = rootElement.element("p1");
        // 获取age
        Element age = p1.element("age");
        // 修改age的值
        age.setText("99");
        // 回写xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }

五、使用dom4j删除节点的操作
跳转到目录

删除第一个p1下面的school元素

  • remove(要删除的元素对象) 删除元素
 // 删除第一个p1下面的school元素
    public static void deleteSchoolEle() throws Exception {
        /*
         * 1. 得到document
         * 2. 获取根节点
         * 3. 得到第一个p1标签
         * 4. 获取p1下的school元素
         * 5. 删除(使用p1来删除school)
         * 6. 回写xml
         * */
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        Element rootElement = document.getRootElement();
        Element p1 = rootElement.element("p1");
        Element school = p1.element("school");
        // 删除school元素
        // 获取父节点方法(通过父节点来删除)
        // school.getParent(); // 获取school的父节点
        p1.remove(school);
        // 回写xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }

六、使用dom4j获取属性的操作
跳转到目录

获取第一个p1元素的属性id1的值

  • attributeValue("属性名") 获取属性值
    // 获取第一个p1元素的属性id1的值
    public static void getValues() throws Exception{
        /*
        * 1. 得到document
        * 2. 获取根节点
        * 3. 获取第一个p1元素
        * 4. 获取p1的属性值
        * 		p1.attributeValue("属性名称");
        * */
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        Element rootElement = document.getRootElement();
        Element p1 = rootElement.element("p1");
        String value = p1.attributeValue("id1");
        System.out.println(value);
    }

使用dom4j支持XPath的操作

跳转到目录

  • 可以直接获取某个元素

获取元素常见形式

  • 第一种形式
    /AAA/BBB/CCC:表示层级结构,表示AAA下面BBB下面的所有CCC
  • 第二种形式
    //BBB:表示和这个名称相同,只要名称是 BBB 都可以获取到
  • 第三种形式
    /AAA/BBB/*:选择目录下的所有元素
    /*/*/*/BBB:选择有三个祖先元素的BBB元素
    //*:选择所有的元素
  • 第四种形式
    //AAA[1]/BBB:选择第一个AAA下的BBB元素
    //AAA/BBB[1]:选择所有AAA的第一个BBB元素
    //AAA/BBB[last()]:选择所有AAA的最后一个BBB元素
  • 第五种形式
    //@id:选择所有的id属性
    //BBB[@id]:选择具有id属性的BBB元素
  • 第六种形式
    //BBB[@id='b1'] :选择含有属性id并且其值为b1的BBB元素
使用dom4j支持XPath具体操作

跳转到目录

  • 导包
    链接:https://pan.baidu.com/s/1PUsL3-2HZfNkK23RRcsRqA
    提取码:yl07
  • 在dom4j里面提供两个方法,用来支持XXPath
    • selectNodes("xpath表达式") - 获取多个节点
    • selectSingleNode("xpath表达式") - 获取一个节点
  • 使用XPath实现: 查询xml中所有name元素的值
    • 所有name元素的xpath表示: //name
    • 使用selectNodes("//name");
    // 查询xml中所有name元素的值
    public static void test1() throws Exception {
        //1. 得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        List<Node> list = document.selectNodes("//name");
        // 遍历
        for (Node node : list) {
            // node 是每一个name元素
            // 得到name元素的值
            String str = node.getText();
            System.out.println(str);
        }
    }
  • 使用XPath实现: 获取第一个p1下面的name的值
    • //p1[@id1='073']/name
    // 获取第一个p1下面的name的值
    public static void test2() throws Exception{
        // 得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        Node name = document.selectSingleNode("//p1[@id1='073']/name");
        // 得到name里面的值
        System.out.println(name.getText());
    }
发布了149 篇原创文章 · 获赞 68 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/m0_37989980/article/details/103802965