XML 解析器——Dom4j

一、Dom4j 技术概述

  先是 Jdom 在 dom 基础上进行了封装,而 dom4j 又对 jdom 进行了封装。

  DOM4J是一个开源的,基于Java的库来解析XML文档,它具有高度的灵活性,高性能和内存效率的API。这是java的优化,使用Java集合像列表和数组。它可以使用DOM,SAX,XPath和XSLT。它解析大型XML文档时具有极低的内存占用。

二、DOM4j 类库

  1、类库

    官网下载需要的 jar 包:Dom4J官网

    Dom4j 在线 API

  2、使用

    dom4j 的 jar包:

    

    docs 是文档目录:

    

     在docs 里面找到 index.html ,快速入门

    

三、DOM4j 解析步骤

  步骤

1、先加载 xml 文件创建 Document 对象

2、通过 Document 对象拿到根元素对象

3、通过根元素.elelemts(标签名); 可以返回一个集合, 这个集合里放着。 所有你指定的标签名的元素对象
4、获取需要操作的元素,进行相应的操作

  XML 文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <books>
 3 <book sn="123">
 4     <name>Java</name>
 5     <price>9.9</price>
 6     <author>老张</author>
 7 </book>
 8 <book sn="456">
 9     <name>Python</name>
10     <price>99.99</price>
11     <author>老李</author>
12 </book>
13 </books>

  测试解析文件:

 1     /*
 2      * dom4j 获取 Documet 对象
 3      */
 4     @Test
 5     public void getDocument() throws DocumentException {
 6         // 要创建一个 Document 对象, 需要我们先创建一个 SAXReader 对象
 7         SAXReader reader = new SAXReader();
 8         // 这个对象用于读取 xml 文件, 然后返回一个 Document。
 9         Document document = reader.read("src/books.xml");
10         // 打印到控制台, 看看是否创建成功
11         System.out.println(document);
12     }

  解析XML文件:

 1 /*
 2  * 读取 xml 文件中的内容
 3  */
 4 @Test
 5 public void readXML() throws DocumentException {
 6     // 需要分四步操作:
 7     // 第一步, 通过创建 SAXReader 对象。 来读取 xml 文件, 获取 Document 对象
 8     // 第二步, 通过 Document 对象。 拿到 XML 的根元素对象
 9     // 第三步, 通过根元素对象。 获取所有的 book 标签对象
10     // 第四步, 遍历每个 book 标签对象。 然后获取到 book 标签对象内的每一个元素, 再通过 getText() 方法拿到起始标签和结束标签之间的文本内容
11     // 第一步, 通过创建 SAXReader 对象。 来读取 xml 文件, 获取 Document 对象
12       SAXReader reader = new SAXReader();
13       Document document = reader.read("src/books.xml");
14     // 第二步, 通过 Document 对象。 拿到 XML 的根元素对象
15        Element root = document.getRootElement();
16     // 打印测试
17     // Element.asXML() 它将当前元素转换成为 String 对象
18     // System.out.println( root.asXML() );
19     // 第三步, 通过根元素对象。 获取所有的 book 标签对象
20     // Element.elements(标签名)它可以拿到当前元素下的指定的子元素的集合
21        List<Element> books = root.elements("book");
22     // 第四步, 遍历每个 book 标签对象。 然后获取到 book 标签对象内的每一个元素,
23        for (Element book : books) {
24       // 测试
25       // System.out.println(book.asXML());
26       // 拿到 book 下面的 name 元素对象
27          Element nameElement = book.element("name");
28       // 拿到 book 下面的 price 元素对象
29          Element priceElement = book.element("price");
30       // 拿到 book 下面的 author 元素对象
31          Element authorElement = book.element("author");
32       // 再通过 getText() 方法拿到起始标签和结束标签之间的文本内容
33          System.out.println("书名" + nameElement.getText() + " , 价格:"
34           + priceElement.getText() + ", 作者: " + authorElement.getText());
35           }
36 }

四、Dom4j 解析器使用 XPath 语言操作 xml 文档

  1、导入支持 xpath 的 jar 包:jaxen-1.1-beta-6.jar

  2、dom4j 里面提供了两个方法,用来支持 XPath

selectNodes("XPath 表达式"); 表示获取多个节点
selectSingleNode("XPath 表达式"); 表示获取单个节点

  Demo:

 1     @Test
 2     public void test() throws Exception {
 3         //创建核心解析器对象
 4         SAXReader saxReader = new SAXReader();
 5         //加载配置文件,获取文档对象document
 6         InputStream is = Dom4jDemo.class.getClassLoader().getResourceAsStream("student.xml");
 7         //获取 document 对象
 8         Document document = saxReader.read(is);
 9         //使用xpath语法快速查找元素,返回List集合
10         List<Element> list = document.selectNodes("//name");
11         for (Element element : list) {
12             String id = element.attributeValue("id");
13             String text = element.getText();
14             System.out.println(text);
15         }
16         //查找age标签,标签上有aaa属性的元素
17         List<Element> ages = document.selectNodes("//age[@aaa]");
18         //查找age标签,并且标签aaa=dsas
19         Element age =(Element) document.selectSingleNode("//age[@aaa='dsas']");
20         System.out.println(age.getText());
21     }

五、Dom4j 操作 XML 文档

  1、使用 dom4j 解析 xml

    步骤:

    (1)得到 document 对象

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

    (2)Document 接口的父接口是 Node

      如果在 Document 里面找不到想要的方法,可以去Node里面找。

      Document常用方法:

DocumentType docType = document.getDocType();           //获取文档类型
String xmlEncoding = document.getXMLEncoding();         //获取文件编码
Document document1 = document.getDocument();            //获取整个文档
String name = document.getName();                       //获取文档名字
String path = document.getPath();                       //获取文档路径
Element rootElement = document.getRootElement();        //获取根节点,返回 Element 对象

  

    (3)Element 也是一个接口,父接口是 Node

      Element 常用方法:

getParent();        获取父节点
element(标签的名称): 获取标签下面是 这个标签名 的 第一个 子标签
elements():         获取标签下面的 所有 一层子标签
elements(标签的名称):获取标签下面是 这个标签名 的 所有 一层子标签

  

    (4)案例

 1     @Test
 2     //功能:解析xml文档
 3     public void test() throws DocumentException {
 4         //1、得到document对象
 5         SAXReader reader = new SAXReader();
 6         Document document = reader.read("src/books.xml");
 7 
 8         //2、获取根元素,返回 Element 对象
 9         Element root = document.getRootElement();
10 
11         //element(标签的名称)获取标签下面是 这个标签名 的 所有 一层子标签
12         List<Element> books = root.elements("book");
13         for (Element book : books) {
14             System.out.println("book.asXML() = " + book.asXML());
15         }
16 
17         //elements() 获取标签下面的 所有 一层子标签。
18         List<Element> elements = root.elements();
19         for (Element element : elements) {
20             System.out.println("element.asXML() = " + element.asXML());
21         }
22 
23         //element(标签的名称)  获取标签下面是 这个标签名 的 第一个 子标签
24         Element book = root.element("book");
25         System.out.println("book.asXML() = " + book.asXML());
26         
27         // getParent() 获取父节点
28         Element parent = book.getParent();
29         System.out.println("parent.asXML() = " + parent.asXML());
30 
31     }

  2、使用 dom4j 查询 xml

    步骤:

1、创建解析器,得到 document 对象

2、得到根节点 getRootElement() 返回Element

3、得到需要的标签,根据需要返回一个或多个(List集合)

4、通过 getText() 方法获取里面的值或使用 elementText(标签名) 获取里面的值 

    Demo:

 1     @Test
 2     //功能:查询
 3     //需求:查询所有元素里面的值
 4     public void test() throws DocumentException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取根节点下面一层的所有 book 元素
13         List<Element> book = root.elements("book");
14         for (Element element : book) {
15             //1)得到 book 下面的 name元素
16             Element name = element.element("name");
17             //得到 name 里面的文本值
18             String nameText = name.getText();
19 
20             //2)elementText(标签名) 直接获取指定标签名的文本内容
21             String price = element.elementText("price");
22             String author = element.elementText("author");
23 
24             System.out.println("name=" + nameText + ";price=" + price + ";author=" + author);
25 
26         }
27     }

  3、使用 dom4j 实现添加操作

    步骤:

1、创建解析器,得到document对象

2、获取根元素,返回 Element 对象

3、获取第一个 book节点

4、在 book节点下面添加元素,并给元素添加文本内容或属性

5、回写 xml

    Demo:

 1     @Test
 2     //功能:添加
 3     //需求:在第一个 book 末尾添加 <sex>nv</sex> 元素
 4     public void test06() throws DocumentException, IOException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取第一个 book节点
13         Element book = root.element("book");
14 
15         //4、在 book节点下面添加元素
16         Element sex = book.addElement("sex");
17 
18         //5、在添加完成之后给元素添加文本内容
19         sex.setText("nv");
20         //添加属性和值
21         sex.setAttributeValue("abc","abc");
22 
23         //6、回写 xml(以上的操作都是在对内存中的Document对象的处理,必须回写到硬盘上才能更改)
24         //OutputFormat format = OutputFormat.createCompactFormat();  //压缩格式的,不便于阅读
25 
26         OutputFormat format = OutputFormat.createPrettyPrint(); //可以有缩进的效果
27 
28         XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"),format);
29 
30         xmlWriter.write(document);
31         xmlWriter.close();
32     }

  4、使用 dom4j 实现在特定位置添加元素

    步骤:

1、创建解析器,得到document对象

2、获取根元素,返回 Element 对象

3、获取第一个 book节点

4、获取 book 下面的所有的元素,返回一个 List

5、使用 DocumentHelper类方法 createElement 创建标签,使用 setText(文本) 方法,添加文本,使用 setAttributeValue(s1,s2) 添加属性

6、添加到 list 集合中:add(int index, E element) 第一个参数是位置,下标,从0开始,第二个参数是要添加的元素

7、回写 xml

    Demo:

 1     @Test
 2     //功能:在特定位置添加元素
 3     //需求:在第一个 book 下面的 author 之前添加 <addr>北京</addr>
 4     public void test07() throws DocumentException, IOException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取第一个 book
13         Element book = root.element("book");
14 
15         //4、获取 book 下面的所有的元素
16         List<Element> elements = book.elements();
17 
18         //5、创建要添加的元素,使用DocumentHelper。末尾添加不用,指定位置添加要创建元素
19         Element addr = DocumentHelper.createElement("addr");
20         //给 addr 下面创建文本
21         addr.setText("北京");
22         addr.setAttributeValue("abc","abc");
23 
24         //6、在需要的位置添加
25         elements.add(2,addr);
26 
27         //7、回写 xml
28         OutputFormat format = OutputFormat.createPrettyPrint();
29         XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
30         xmlWriter.write(document);
31         xmlWriter.close();
32 
33     }

     Tips   

    可以对得到document的操作和 回写xml的操作,封装成方法,也可以把传递的文件路径,封装成一个常量
    好处:可以提高开发速度,可以提交代码可维护性

  5、使用 dom4j 实现 修改节点的操作

    步骤:

1、创建解析器,得到document对象

2、获取根元素,返回 Element 对象

3、获取第一个 book节点

4、获取要修改的结点,使用 setText() 方法修改内容

5、回写 xml 

    Demo:

 1     @Test
 2     //功能:修改节点
 3     //需求:修改第一个 book 下面的 <price>19.9</price>
 4     public void test08() throws DocumentException, IOException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取第一个 book
13         Element book = root.element("book");
14 
15         //4、获取第一个 book 下面的 price
16         Element price = book.element("price");
17 
18         //5、修改内容
19         price.setText("19.9");
20 
21         //6、回写 xml
22         OutputFormat format = OutputFormat.createPrettyPrint();
23         XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
24         xmlWriter.write(document);
25         xmlWriter.close();
26     }

  6、使用 dom4j 实现 删除节点的操作

    步骤:

1、创建解析器,得到document对象

2、获取根元素,返回 Element 对象

3、获取第一个 book节点

4、获取要删除的结点和它的父节点,使用父节点的 remove(元素) 方法删除节点

5、回写 xml

    Demo:

 1     @Test
 2     //功能:删除节点
 3     //需求:修改第一个 book 下面的 <addr abc="abc">北京</addr>
 4     public void test09() throws DocumentException, IOException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取第一个 book
13         Element book = root.element("book");
14 
15         //4、获取第一个 book 下面的 addr 元素
16         Element addr = book.element("addr");
17 
18         //5、
19         //book.remove(addr);   book 为 addr的父节点,可直接获取
20         //或者使用 getParent() 方法获取父节点,然后再删除
21         Element parent = addr.getParent();
22         boolean flag = parent.remove(addr);
23         System.out.println(flag);
24 
25         //6、回写 xml
26         OutputFormat format = OutputFormat.createPrettyPrint();
27         XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
28         xmlWriter.write(document);
29         xmlWriter.close();
30     }

  7、使用 dom4j 获取 属性的操作

    步骤:

1、创建解析器,得到document对象

2、获取根元素,返回 Element 对象

3、获取第一个 book节点

4、使用 attributeValue(属性名) 获取属性值

    Demo:

 1     @Test
 2     //功能:获取属性的值
 3     //需求:获取第一个 book 中的属性 sn 的值
 4     public void test10() throws DocumentException {
 5         //1、创建解析器,得到document对象
 6         SAXReader reader = new SAXReader();
 7         Document document = reader.read("src/books.xml");
 8 
 9         //2、获取根元素,返回 Element 对象
10         Element root = document.getRootElement();
11 
12         //3、获取第一个 book
13         Element book = root.element("book");
14 
15         //4、获取 book 中属性值,里面的参数是属性名称
16         String sn = book.attributeValue("sn");
17         System.out.println("sn = " + sn);
18     }
原文地址:https://www.cnblogs.com/niujifei/p/15093848.html