zoukankan      html  css  js  c++  java
  • 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     }
  • 相关阅读:
    Path Sum
    Binary Tree Level Order Traversal II
    Jump Game
    leedcode 刷题-V2
    (2016 年) githup 博客地址 : https://github.com/JMWY/MyBlog
    算法分类总结
    剑指 Offer 题目汇总索引
    LeedCde 题解目录
    趣味算法总目录
    常用
  • 原文地址:https://www.cnblogs.com/niujifei/p/15093848.html
Copyright © 2011-2022 走看看