dom4J使用笔记

Posted OverZeal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dom4J使用笔记相关的知识,希望对你有一定的参考价值。

使用dom4j是目前最常用的解析XML的方法,dom4j解析集DOM和SAX技术优点于一身,要使用dom4j 还是先要导入jar:

dom4j-1.6.1.jar (dom4j最主要的jar包,可以独立存在)  , jaxen-1.1.6.jar (支持Xpath技术)

需要解析的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<person> 
  <student id="123"> 
    <name>lz</name>  
    <age>21</age> 
  </student>  
  <student> 
    <name>zhanshang</name>  
    <age>20</age> 
  </student> 
</person>

dom4j解析的步骤:

步骤一:得到Document对象

        //1.创建解析器
        SAXReader reader=new SAXReader();
        //2.解析XML文件,得到Document
        Document document = reader.read(url);

步骤二 调用Document对象的getRootElement()方法得到根标签,返回的是Element对象

        Element root = document.getRootElement();

步骤三 使用ELement的API进行操作,如果没找到想要的方法,可以到其父接口Node中寻找,注意:这里使用的类都是org.dom4j 包下的

Element对象常用的方法:element("标签名")获得该标签的第一个元素  elements()获得所有的子标签 elements("标签名")获得所有的该标签的子元素 getParent()获得父节点 addElement()添加标签 getText()获得文本值 setText("文本值")设置文本值

查询元素

查询操作主要是用elementelements方法

/**
     * 查询所有name和age的值
     * @throws Exception 
     */
    @Test
    public void fun1() throws Exception{
        //1.创建解析器
        SAXReader reader=new SAXReader();
        //2.解析XML文件,得到Document
        Document document = reader.read("src/person.xml");
        //3.得到根标签
        Element root = document.getRootElement();
        //4.进行具体操作
        List<Element> elements = root.elements("student");
        for (Element element : elements) {
            Element name = element.element("name");
            String nameText = name.getText();
            Element age = element.element("age");
            String ageText = age.getText();
            System.out.println("name:"+nameText+" age:"+ageText);
        }
    }

结果输出:

name:lz age:21
name:zhanshang age:20

查询出某一个元素

查询一:

    /**
     * 查询得到第一个student标签的name
     * @throws Exception 
     */
    @Test
    public void fun2() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        Element student = root.element("student");
        Element name = student.element("name");
        System.out.println(name.getText());
    }

输出结果为:

lz

查询二:

/**
     * 查询得到第二个student标签的age
     * @throws Exception 
     */
    @Test
    public void fun3() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        List<Element> students = root.elements("student");
        Element student2 = students.get(1);
        Element age = student2.element("age");
        System.out.println(age.getText());
    }

输出结果为:

20

在末尾添加节点

先要确定要添加位置的父节点,然后使用该父节点的addElement("标签名")添加节点,需要添加文本节点的话使用setText("文本值")方法,最后别忘了回写XML

/**
     * 在末尾添加节点
     * @throws Exception 
     */
    @Test
    public void fun4() throws Exception{
        //1.创建解析器
        SAXReader reader=new SAXReader();
        //2.解析XML文件得到Document
        Document document = reader.read("src/person.xml");
        //3.得到根标签
        Element root = document.getRootElement();
        //在第一个student元素后添加school
        Element student = root.element("student");
        Element school = student.addElement("school");
        school.setText("lynu");
        //回写XML
        OutputFormat format=OutputFormat.createPrettyPrint();  //带缩进的格式
        XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format);
        writer.write(document);
        writer.close();
    }

回写XML使用的是OutputFormat类和XMLWriter类,这两个类都是org.dom4j.io 包下的,OutputFormat 类还有个createCompactFormat()方法可以压缩XML文件中的空格和换行,使用dom4j不会像jaxp那样破坏XML文件的格式。因为XMLWriter类使用流的技术,所以要记得使用完关闭

结果显示为:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <student id="123"> 
    <name>lz</name>  
    <age>21</age>  
    <school>lynu</school>
  </student>  
  <student> 
    <name>zhanshang</name>  
    <age>20</age> 
  </student> 
</person>

第一个student标签多了个school子标签

在特定位置添加节点

其实在特定位置添加元素就是使用父节点调用elements()方法的其子元素列表,是一个List集合,接下来就是操作List集合,使用List的add(位置,标签) ,当然不要忘了再添加将集合前,将这个元素创建出来:DocumentHelper.createElement(标签名) ,DocumentHelper类也是org.dom4j 包下的

    /**
     * 在特定位置(第二个student的age前面)添加school节点
     * @throws Exception 
     */
    @Test
    public void fun5() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        Element student2 = (Element) root.elements().get(1);  //得到第二个student
        List<Element> elements = student2.elements();    //得到student的子标签集合
        Element school = DocumentHelper.createElement("school");  //创建school节点
        school.setText("lynu");
        elements.add(1, school);     //在对应为位置添加(操作list集合)
        //回写XML
        OutputFormat format=OutputFormat.createPrettyPrint();
        XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format);
        writer.write(document);
        writer.close();
    }

结果显示为:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <student id="123"> 
    <name>lz</name>  
    <age>21</age>  
    <school>lynu</school> 
  </student>  
  <student> 
    <name>zhanshang</name>  
    <school>lynu</school>
    <age>20</age> 
  </student> 
</person>

第二个student也都添加了school子节点

修改节点的值

修改节点就是先找到需要修改的节点,然后使用setText("文本值")

 

/**
     * 修改节点的值
     * @throws Exception 
     */
    @Test
    public void fun6() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        Element student1 = root.element("student");
        Element age1 = student1.element("age");
        age1.setText("100");
        OutputFormat format=OutputFormat.createPrettyPrint();
        XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format);
        writer.write(document);
        writer.close();
    }
    

 

结果显示为:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <student id="123"> 
    <name>lz</name>  
    <age>100</age>  
    <school>lynu</school> 
  </student>  
  <student> 
    <name>zhanshang</name>  
    <school>lynu</school>  
    <age>20</age> 
  </student> 
</person>

第一个student的age修改为100

删除节点

删除节点还是需要先找到其父节点,然后根据父节点调用remove(节点)删除

    /**
     * 删除节点(删除所有school)
     * @throws Exception 
     */
    @Test
    public void fun7() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        List<Element> elements = root.elements("student");
        for (Element element : elements) {
            //删除节点,需要根据要删除节点的父节点来删除
            Element school = element.element("school");   //得到要删除的节点
            element.remove(school);
        }
        //回写XML
        OutputFormat format=OutputFormat.createPrettyPrint();
        XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format);
        writer.write(document);
        writer.close();
    }

结果显示为:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <student id="123"> 
    <name>lz</name>  
    <age>100</age> 
  </student>  
  <student> 
    <name>zhanshang</name>  
    <age>20</age> 
  </student> 
</person>

所有的school标签被删除了

获得属性的值

先得到对应的标签,然后使用attributeValue("属性名")得到属性值

/**
     * 获得属性值
     * @throws Exception 
     */
    @Test
    public void fun8() throws Exception{
        SAXReader reader=new SAXReader();
        Document document = reader.read("src/person.xml");
        Element root = document.getRootElement();
        Element student1 = root.element("student");
        String id = student1.attributeValue("id");
        System.out.println(id);
    }

结果输出为:

123

第一个student标签上有一个id属性,id属性值为123

XPath

获取某个元素使用dom4j原生的方法虽然很方便,但是使用XPath之后会发现获得一个元素更为方便了,使用dom4j支持XPath就需要 jaxen-1.1.6.jar zhegejar包,先来看看Xpath的语法:

第一种形式:/AAA/DDD/BBB 表示一层一层获得AAA下面的DDD下面的BBB

第二种形式://BBB 表示只要名为BBB的都可以获得

第三种形式:/* 所有元素

第四种形式:BBB[1]表示第一个BBB元素   BBB[last()]表示最后一个BBB元素

第五种形式://BBB[@id] 表示获得所有有id属性的BBB元素

第六种形式://BBB[@id=‘1‘] 表示元素名为BBB,BBB元素有id属性,且属性值为1的元素

dom4j提供了两个方法用于支持XPath : selectNodes("XPath表达式") 获得多个节点, selectSingleNode("XPath表达式") 获得一个节点

获得标签的值

    /**
     * 获得所有name标签的值
     * @throws Exception
     */
    @Test
    public void fun1() throws Exception{
        //1.获得document
        Document document = new SAXReader().read("src/person.xml");
        //2.调用Document对象的API,使用XPath表达式
        List<Node> list = document.selectNodes("//name");
        //遍历输出
        for (Node node : list) {
            System.out.println(node.getText());
        }
    }

 结果输出为:

lz
zhanshang

获得某一个标签的值

/**
     * 获得某一个标签(name)的值
     * @throws Exception 
     */
    @Test
    public void fun2() throws Exception{
        Document document = new SAXReader().read("src/person.xml");
        Node node = document.selectSingleNode("//student[@id=‘123‘]/name");  //获得某一个标签
        System.out.println(node.getText());
    }

结果输出为:

lz

 

以上是关于dom4J使用笔记的主要内容,如果未能解决你的问题,请参考以下文章

XML学习笔记--dom4j操作XML

学习笔记:python3,代码片段(2017)

使用dom4j解析xml

使用dom4j创建和解析xml文件

dom4j读取xml

Dom4j