XML 的学习笔记3

XML 解析

简单的说,对XML文档的解析就是,操作xml文档,将文档中的数据读取到内存中。

  1. 操作xml文档
    1. 解析(读取):将文档中的数据读取到内存中
    2. 写入:将内存中的数据保存到xml文档中。持久化的存储

解析xml的方式

解析XML的方式有两种,DOM 和 SAX。

DOM方式解析xml文档

将标记语言文档一次性加载进内存,在内存中形成一棵dom树。

  • 优点:操作方便,可以对文档进行CRUD的所有操作
  • 缺点:占内存

SAX方式解析xml文档

该方式是逐行读取,基于事件驱动的。

  • 优点:不占内存。读取一部分内容进内存,释放释放一部分内存。
  • 缺点:只能读取,不能增删改

xml常见的解析器

  1. JAXP:sun公司提供的解析器,支持dom和sax两种思想
  2. DOM4J:一款非常优秀的解析器
  3. Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
  4. PULL:Android操作系统内置的解析器,sax方式的。

使用 Jsoup 解析 XML

快速入门

  1. 下载 Jsoup架包:jsoup-1.13.1.jarjsoup-1.13.1-sources.jarjsoup-1.13.1-javadoc.jar

    备注:JSoup 官网

  2. 导入 Jsoup架包,这里使用的IDEA编程工具:

    1. 在项目目录下创建一个文件夹(libs),用来放架包

      JsoupJarLibs.png
    2. 将下载好的架包复制到libs目录下

      JsoupJarLibs02.png
    3. 导入架包

      JsopJarLibs03.png JsopJarLibs04.png

      这里就已经将架包导入到项目中了。

  3. 创建一个xml文件,用于后面的使用

    <?xml version="1.0" encoding="UTF-8"?>
    <students>
        <student number="stringbug_2020">
            <name>Lee Hua</name>
            <age>21</age>
            <sex>male</sex>
        </student>
        <student number="stringbug_2018">
            <name>Rainbow</name>
            <age>20</age>
            <sex>female</sex>
        </student>
    </students>
    
  4. 创建一个demo,获取document对象

    1. 获取上面创建的xml文件路径,创建该文件对象:student.xml

      // 获取 JsoupDemo01 的字节码对象
      Class<JsoupDemo01> jsoupDemo01Class = JsoupDemo01.class;
      // 获取 JsoupDemo01.class 的类加载器
      ClassLoader classLoader = jsoupDemo01Class.getClassLoader();
      // 找到对应的资源位置:student.xml 文件位置
      URL resource = classLoader.getResource("jsoup/student.xml");
      // 获取 student.xml 路径的字符串标示形式
      String path = resource.getPath();
      // 创建文件对象
      File file = new File(path);
      
    2. 解析xml文档,将xml文档内容加载进内存,获取dom树

      Document parse = Jsoup.parse(file, "utf-8");
      
    3. 获取xml文件内容

      1. 根据标签的名称获取xml文件内容

        // 获取元素对象
        Elements name = parse.getElementsByTag("name");
        // 输出获取到标签内容
        for (int i = 0; i < name.size(); i++) {
            System.out.println(name.get(i));
            System.out.println("------------");
        }
        
        // 输出结果如下
        <name>
         Lee Hua
        </name>
        ------------
        <name>
         Rainbow
        </name>
        ------------
        
      2. 获取标签中的文本内容

        // 获取元素对象
        Elements name = parse.getElementsByTag("name");
        for (int i = 0; i < name.size(); i++) {
            // 输出获取到的标签文本内容
            System.out.println(name.get(i).text());
            System.out.println("------------");
        }
        
        // 输出结果如下
        Lee Hua
        ------------
        Rainbow
        ------------
        
  5. 实例代码汇总

    1. jsoup/student.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <students>
          <student number="stringbug_2020">
              <name>Lee Hua</name>
              <age>21</age>
              <sex>male</sex>
          </student>
          <student number="stringbug_2018">
              <name>Rainbow</name>
              <age>20</age>
              <sex>female</sex>
          </student>
      </students>
      
    2. jsoup/

      import org.jsoup.Jsoup;
      import org.jsoup.nodes.Document;
      import org.jsoup.select.Elements;
      
      import java.io.File;
      import java.io.IOException;
      import java.net.URISyntaxException;
      import java.net.URL;
      
      public class JsoupDemo01 {
          public static void main(String[] args) throws IOException, URISyntaxException {
      
              // 获取 JsoupDemo01.java 的字节码对象
              Class<JsoupDemo01> jsoupDemo01Class = JsoupDemo01.class;
              // 获取 JsoupDemo01.class 的类加载器
              ClassLoader classLoader = jsoupDemo01Class.getClassLoader();
              // 找到对应的资源位置:student.xml 文件位置
              URL resource = classLoader.getResource("jsoup/student.xml");
              // 获取 student.xml 路径的字符串标示形式
              String path = resource.getPath();
              // 创建文件对象
              File file = new File(path);
      
              // 解析xml文档,将xml文档内容加载进内存,获取dom树
              Document parse = Jsoup.parse(file, "utf-8");
      
              // 获取元素对象
              Elements name = parse.getElementsByTag("name");
              for (int i = 0; i < name.size(); i++) {
                  System.out.println(name.get(i));
                  System.out.println("------------");
              }
              for (int i = 0; i < name.size(); i++) {
                  System.out.println(name.get(i).text());
                  System.out.println("------------");
              }
          }
      }
      

对象的使用

  1. Jsoup:工具类,可以解析html或xml文档,返回Document

    • parse:解析html或xml文档,返回Document

      parse​(File in, String charsetName)
      // 解析xml或html文件的。
      
      parse​(String html)
      // 解析xml或html字符串
      
      parse​(URL url, int timeoutMillis)
      // 通过网络路径获取指定的html或xml的文档对象
      
  2. Document:文档对象。代表内存中的dom树

    • 获取Element对象

      getElementById​(String id)
      // 根据id属性值获取唯一的element对象
        
      getElementsByTag​(String tagName)
      // 根据标签名称获取元素对象集合
        
      getElementsByAttribute​(String key)
      // 根据属性名称获取元素对象集合
        
      getElementsByAttributeValue​(String key, String value)
      // 根据对应的属性名和属性值获取元素对象集合
      
  3. Elements:元素Element对象的集合。可以当做 ArrayList来使用

  4. Element:元素对象

    1. 获取子元素对象

      getElementById​(String id)
      // 根据id属性值获取唯一的element对象
        
      getElementsByTag​(String tagName)
      // 根据标签名称获取元素对象集合
        
      getElementsByAttribute​(String key)
      // 根据属性名称获取元素对象集合
        
      getElementsByAttributeValue​(String key, String value)
      // 根据对应的属性名和属性值获取元素对象集合
      
    2. 获取属性值

      String attr(String key)
      // 根据属性名称获取属性值
      
    3. 获取文本内容

      String text()
      // 获取文本内容
      
      String html()
      // 获取标签体的所有内容(包括字标签的字符串内容)
      
  5. Node:节点对象(了解即可)

    Node 是Document和Element的父类。

Jsoup 工具类的使用
  1. parse(File in, String charsetName) 解析xml或html文件。

    // parse(File in, String charsetName) 解析xml或html文件。
    // 获取student.xml的path
    String path = JsoupDemo02.class.getClassLoader().getResource("jsoup/student.xml").getPath();
    // 解析xml文档,将xml文档内容加载进内存,获取dom树
    Document document1 = Jsoup.parse(new File(path), "utf-8");
    // 输出的内容是 student.xml 文档的所有内容
    System.out.println(document1);
    
  2. parse(String html) 解析xml或html字符串

    String xml = "<student number=\"stringbug_2020\">\n" +
            "    <name>Lee Hua</name>\n" +
            "    <age>21</age>\n" +
            "    <sex>male</sex>\n" +
            "</student>\n" +
            "<student number=\"stringbug_2018\">\n" +
            "    <name>Rainbow</name>\n" +
            "    <age>20</age>\n" +
            "    <sex>female</sex>\n" +
            "</student>";
    Document document2 = Jsoup.parse(xml);
    System.out.println(xml);
    
  3. parse(URL url, int timeoutMillis) 通过网络路径获取指定的html或xml的文档对象

    URL url = new URL("https://www.baidu.com/");
    Document document3 = Jsoup.parse(url, 10000);
    System.out.println(document3);
    
  4. 代码汇总

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    
    public class JsoupDemo03 {
        public static void main(String[] args) throws IOException {
            // parse(File in, String charsetName) 解析xml或html文件。
            // 获取student.xml的path
            String path = JsoupDemo02.class.getClassLoader().getResource("jsoup/student.xml").getPath();
            // 解析xml文档,将xml文档内容加载进内存,获取dom树
            Document document1 = Jsoup.parse(new File(path), "utf-8");
            // 输出的内容是 student.xml 文档的所有内容
            System.out.println(document1);
    
            System.out.println("===============================================================================");
    
            // parse(String html) 解析xml或html字符串
            String xml = "<student number=\"stringbug_2020\">\n" +
                    "    <name>Lee Hua</name>\n" +
                    "    <age>21</age>\n" +
                    "    <sex>male</sex>\n" +
                    "</student>\n" +
                    "<student number=\"stringbug_2018\">\n" +
                    "    <name>Rainbow</name>\n" +
                    "    <age>20</age>\n" +
                    "    <sex>female</sex>\n" +
                    "</student>";
            Document document2 = Jsoup.parse(xml);
            System.out.println(document2);
    
            System.out.println("===============================================================================");
    
            // parse(URL url, int timeoutMillis) 通过网络路径获取指定的html或xml的文档对象
            URL url = new URL("https://www.baidu.com/");
            Document document3 = Jsoup.parse(url, 10000);
            System.out.println(document3);
        }
    }
    

    student.xml 文件在当前 .java 文件所在的目录下

Element元素对象的使用
  1. xml字符串内容如下:

    XmlString.png

    解析xml字符串

    Document document = Jsoup.parse(xml);
    
  2. getElementById(String id) 根据id属性值获取唯一的element对象

    Element elementById = document.getElementById("666");
    System.out.println(elementById);
    
  3. getElementsByTag(String tagName) 根据标签名称获取元素对象集合

    Elements elementsByTag = document.getElementsByTag("sex");
    System.out.println(elementsByTag);
    
  4. getElementsByAttribute(String key) 根据属性名称获取元素对象集合

    Elements elementsByAttribute = document.getElementsByAttribute("number");
    System.out.println(elementsByAttribute);
    
  5. getElementsByAttributeValue(String key, String value) 根据对应的属性名和属性值获取元素对象集合

    Elements elementsByAttributeValue = document.getElementsByAttributeValue("number", "stringbug_2018");
    System.out.println(elementsByAttributeValue);
    
  6. 代码汇总

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.io.IOException;
    
    public class JsoupDemo04 {
        public static void main(String[] args) throws IOException {
            // 解析xml或html字符串
            String xml = "<student id=\"666\" number=\"stringbug_2020\">\n" +
                    "    <name>Lee Hua</name>\n" +
                    "    <age>21</age>\n" +
                    "    <sex>male</sex>\n" +
                    "</student>\n" +
                    "<student number=\"stringbug_2018\">\n" +
                    "    <name>Rainbow</name>\n" +
                    "    <age>20</age>\n" +
                    "    <sex>female</sex>\n" +
                    "</student>";
            Document document = Jsoup.parse(xml);
    
            // getElementById(String id) 根据id属性值获取唯一的element对象
            Element elementById = document.getElementById("666");
            System.out.println(elementById);
    
            System.out.println("===============================================================================");
    
            // getElementsByTag(String tagName) 根据标签名称获取元素对象集合
            Elements elementsByTag = document.getElementsByTag("sex");
            System.out.println(elementsByTag);
    
            System.out.println("===============================================================================");
    
            // getElementsByAttribute(String key) 根据属性名称获取元素对象集合
            Elements elementsByAttribute = document.getElementsByAttribute("number");
            System.out.println(elementsByAttribute);
    
            System.out.println("===============================================================================");
    
            // getElementsByAttributeValue(String key, String value) 根据对应的属性名和属性值获取元素对象集合
            Elements elementsByAttributeValue = document.getElementsByAttributeValue("number", "stringbug_2018");
            System.out.println(elementsByAttributeValue);
        }
    }
    

选择器查询XML内容

<?xml version="1.0" encoding="UTF-8"?>
<students>
    <student id="string" number="stringbug_2020">
        <name>Lee Hua</name>
        <age>21</age>
        <sex>male</sex>
    </student>
    <student number="stringbug_2018">
        <name>Rainbow</name>
        <age>20</age>
        <sex>female</sex>
    </student>
</students>
  1. 选择name标签

    Elements name = document.select("name");
    System.out.println(name);
    
  2. 选择 id="sting" 的标签

    Elements idString = document.select("#string");
    System.out.println(idString);
    
  3. 选择 id="srting" 的标签 下的 name 标签

    Elements idStringName = document.select("#string name");
    System.out.println(idStringName);
    
  4. 代码汇总

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    public class JsoupDemo05 {
        public static void main(String[] args) throws IOException {
            // 获取student.xml的path
            String path = JsoupDemo02.class.getClassLoader().getResource("jsoup/student.xml").getPath();
            // 解析xml文档,将xml文档内容加载进内存,获取dom树
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            // 通过CSS选择器,选择name标签
            Elements name = document.select("name");
            System.out.println(name);
    
            System.out.println("===============================================================================");
    
            // 通过CSS选择器,选择 id="string" 的标签
            Elements idString = document.select("#string");
            System.out.println(idString);
    
            System.out.println("===============================================================================");
    
            // 通过CSS选择器,选择 id="sting" 的标签 下的 name 标签
            Elements idStringName = document.select("#string name");
            System.out.println(idStringName);
        }
    }
    

XPath 获取 XML 内容

XPath 概述
  1. XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
  2. 什么是 XPath:
    1. XPath 使用路径表达式在 XML 文档中进行导航
    2. XPath 包含一个标准函数库
    3. XPath 是 XSLT 中的主要元素
    4. XPath 是一个 W3C 标准
XPath 的使用

JsoupXPath-0.3.2.jar 下载地址

  1. 将下载好的架包导入到项目中

  2. 创建一个student.xml文档

    <?xml version="1.0" encoding="UTF-8"?>
    <students>
        <student number="stringbug_2020">
            <name me="2020">Lee Hua</name>
            <age>21</age>
            <sex>male</sex>
        </student>
        <student number="stringbug_2018">
            <name love="2018">Rainbow</name>
            <age>20</age>
            <sex>female</sex>
        </student>
    </students>
    
  3. 在student.xml文档所在的目录下创建一个demo,获取所有student标签

    /*
        "//" 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
        获取所有student标签
     */
    List<JXNode> students = jxDocument.selN("//student");
    for (JXNode student : students) {
        System.out.println(student);
        System.out.println("==========================================");
    }
    
  4. 获取所有student标签,然后再获取student标签下的name标签

    /*
        "/" 从根节点选取。
        获取所有student标签,然后再获取student标签下的name标签
     */
    List<JXNode> names = jxDocument.selN("//student/name");
    for (JXNode name : names) {
        System.out.println(name);
        System.out.println("==========================================");
    }
    
  5. 获取所有student标签,然后再获取student标签下的name标签,且name标签要有me属性

    /*
        //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
        获取所有student标签,然后再获取student标签下的name标签,且name标签要有me属性
     */
    List<JXNode> mes = jxDocument.selN("//student/name[@me]");
    for (JXNode me : mes) {
        System.out.println(me);
        System.out.println("==========================================");
    }
    
  6. 获取所有student标签,然后再获取student标签下的name标签,name标签要有love属性,且属性值为2018

    /*
        //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
        获取所有student标签,然后再获取student标签下的name标签,name标签要有love属性,且属性值为2018
     */
    List<JXNode> loves = jxDocument.selN("//student/name[@love='2018']");
    for (JXNode love : loves) {
        System.out.println(love);
        System.out.println("==========================================");
    }
    
  7. 代码汇总

    import cn.wanghaomiao.xpath.exception.XpathSyntaxErrorException;
    import cn.wanghaomiao.xpath.model.JXDocument;
    import cn.wanghaomiao.xpath.model.JXNode;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    
    public class JsoupDemo06 {
        public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
            // 获取student.xml的path
            String path = JsoupDemo02.class.getClassLoader().getResource("jsoup/student.xml").getPath();
            // 解析xml文档,将xml文档内容加载进内存,获取dom树
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            // 根据document对象,创建JXDocument对象
            JXDocument jxDocument = new JXDocument(document);
    
            /*
                "//" 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
                获取所有student标签
             */
            List<JXNode> students = jxDocument.selN("//student");
            for (JXNode student : students) {
                System.out.println(student);
                System.out.println("==========================================");
            }
    
            /*
                "/" 从根节点选取。
                获取所有student标签,然后再获取student标签下的name标签
             */
            List<JXNode> names = jxDocument.selN("//student/name");
            for (JXNode name : names) {
                System.out.println(name);
                System.out.println("==========================================");
            }
    
            /*
                //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
                获取所有student标签,然后再获取student标签下的name标签,且name标签要有me属性
             */
            List<JXNode> mes = jxDocument.selN("//student/name[@me]");
            for (JXNode me : mes) {
                System.out.println(me);
                System.out.println("==========================================");
            }
    
            /*
                //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
                获取所有student标签,然后再获取student标签下的name标签,name标签要有love属性,且属性值为2018
             */
            List<JXNode> loves = jxDocument.selN("//student/name[@love='2018']");
            for (JXNode love : loves) {
                System.out.println(love);
                System.out.println("==========================================");
            }
        }
    }
    

参考文档

  1. XSD 简易元素
  2. XML和Schema命名空间详解---实例篇
  3. 对XSD schema文件中elementFormDefault属性的理解
  4. 在 XML 文档中引用 Schema
  5. DOM 树
  6. XPath 语法
posted @ 2021-03-04 12:22  LeeHua  阅读(128)  评论(0编辑  收藏  举报