# XML

# 基本概念

XML是可扩展标记语言(Extensible Markup Language),被设计用来存储和传输数据,在1998年,W3C就发布了XML1.0规范;它有个非常成功的前驱——HTML(Hyper Text Markup Language),是由Web的发明者Tim Berners-Lee和同事Daniel W. Connolly于1990年创立的一种标记语言,主要用来显示数据。

# XML和HTML

XML和HTML的主要区别都是:

  • XML主要是传输储存数据;HTML主要是显示数据。
  • XML标签是没有被预定义,可被扩展的,可被用户定义的;HTML标签基本都被定义了。
  • XML的语法严格;HTML语法松散。
  • XML主要用在配置文件、网络传输中;HTML主要用在网页中。

# 语法

  1. xml第一行必须定义为文档声明
  2. xml文档中有且仅有一个根标签
  3. 属性值必须使用引号(单双都可)引起来
  4. 标签必须正确关闭,要么是自闭合标签,要么是成对的开关闭合标签
  5. xml标签名称区分大小写,xml文档的后缀名为.xml

下面是一个xml示例:

<?xml version="1.0" encoding="utf-8" standalone='no' ?>
<?xml-stylesheet type="text/css" href="name.css" ?>
<users>
    <user id='1'>
        <name>wangwu</name>
        <age>25</age>
        <gender>male</gender>
        <br/>
    </user>
    <user id='2'>
        <name>zhenliu</name>
        <age>27</age>
        <gender>female</gender>

        <code>
            if(a &lt; b &amp;&amp; a &gt; c){}
            <![CDATA[
                if(a < b && a > c) {}
            ]]]>
        </code>
    </user>
</users>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

上面name.css为控制name标签的样式变,其内容为:

name{
    color:red;
}
1
2
3

# 组成

  1. 文档声明,它的格式为:<?xml 属性列表 ?>。属性列表有:
    • version:版本号,必须的属性。
    • encoding:编码方式,告知解析引擎当前文档使用的字符集,默认值为ISO-8859-1。
    • standalone:是否独立,它有两个取值:yes(不依赖其他文件)和no(依赖其他文件)。
  2. 指令:结合css:<?xml-stylesheet type="text/css" href="a.css" ?>
  3. 标签:标签名称自定义的,它有一定规则:
    • 名称可以包含字母、数字以及其他的字符。
    • 名称不能以数字或者标点符号开始。
    • 名称不能以字母xml(或者XML、Xml等等)开始,
    • 名称不能包含空格。
  4. 属性:id属性值要唯一。
  5. 文本:CDATA,其格式为:

# 约束

前面说了XML是可以自定义标签的,那对这些标签编写的规则则是约束,它规定xml文档的书写规则。一般一个框架会定义这些规则,而框架的使用者则需要遵守规则编写xml文档。有两种约束技术:

  1. DTD:文档定义类型(DTD)可定义合法的XML文档来构建模块,使用一系列合法的元素来定义文档的结构。DTD可被成行地声明与XML文档中,也可以作为一个外部引用。
  2. Schema:XML Schema是基于XML的DTD替代者,用于描述XML文档结构。

# DTD

DTD相对于Schema技术来说相对简单,引入DTD文档到xml文档中有两种方式:

  • 内部dtd:将约束规则定义在xml文档中

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE students [
        <!ELEMENT students (student+)>
        <!ELEMENT student (name,age,sex)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        <!ATTLIST student number ID #REQUIRED>
    ]>
    
    <students>
        <student number="a1">
            <name>wangwu</name>
            <age>19</age>
            <sex>male</sex>
        </student>
        <student number="b2">
            <name>zhenliu</name>
            <age>24</age>
            <sex>female</sex>
        </student>
    </students>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
  • 外部dtd:将约束的规则定义在外部的dtd文件中,然后在xml中引用进去。

    • 引用本地dtd:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">

    • 引用网络dtd:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">

      student.dtd内容:

      <!ELEMENT students (student+) >
      <!ELEMENT student (name,age,sex)>
      <!ELEMENT name (#PCDATA)>
      <!ELEMENT age (#PCDATA)>
      <!ELEMENT sex (#PCDATA)>
      <!ATTLIST student number ID #REQUIRED>
      
      1
      2
      3
      4
      5
      6

      student.xml内容:

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE students SYSTEM "student.dtd">
      
      <students>
          <student number="a1">
              <name>wangwu</name>
              <age>19</age>
              <sex>male</sex>
          </student>
          <student number="b2">
              <name>zhenliu</name>
              <age>24</age>
              <sex>female</sex>
          </student>
      </students>
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15

# DTD定义解释

上面DTD的定义解释如下:

  1. <!DOCTYPE students:定义此文档为students类型文档。
  2. <!ELEMENT students (student+)>:students元素中最少要出现一个student元素。
  3. <!ELEMENT student (name,age,sex)>:student元素中必须包含name,age,sex元素。
  4. <!ELEMENT name (#PCDATA)>:声明student元素中name元素为PCDATA类型。

# PCDATA和CDATA区别

PCDATA的意思是被解析的字符数据(parsed character data),可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。该标记中下列字符应该被相应实体替换。被解析的字符数据不应当包含任何 字符;需要使用 & < > 实体来分别替换它们。

字符 实体
& &amp;
< &lt;
> &gt;
" &quot;
' &apos;

CDATA的意思是字符数据(character data),它是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

# Schema

XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD),它是基于 XML 的 DTD 替代者,用来描述XML文档的结构。它相对于DTD会复杂一些,对数据类型的支持更完善:

  • 可更容易地描述允许的文档内容
  • 可更容易地验证数据的正确性
  • 可更容易地与来自数据库的数据一并工作
  • 可更容易地定义数据约束(data facets)
  • 可更容易地定义数据模型
  • 可更容易地在不同的数据类型间转换数据

# Schema引用

引入Schema文档步骤: 1.填写xml文档的根元素。 2.引入xsi前缀:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3.引入xsd文件命名空间:xsi:schemaLocation="http://localhost/xml student.xsd" 4.为每一个xsd约束声明一个前缀,作为标识:xmlns="http://localhost/xml"

下面是一个xsd文件:

<?xml version="1.0"?>
<xsd:schema xmlns="http://localhost/xml"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://localhost/xml" elementFormDefault="qualified">
    <xsd:element name="students" type="studentsType"/>
    <xsd:complexType name="studentsType">
        <xsd:sequence>
            <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="studentType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="age" type="ageType" />
            <xsd:element name="sex" type="sexType" />
        </xsd:sequence>
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="sexType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="male"/>
            <xsd:enumeration value="female"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="ageType">
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="test_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

下面是样例引入schema文件:

<?xml version="1.0" encoding="UTF-8"?>
<students xmlns="http://localhost/xml" xmlns:s2="http://localhost/xml2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost/xml student.xsd http://localhost/xml2 student2.xsd">
    <student number="test_0001">
        <name>xie</name>
        <age>20</age>
        <sex>male</sex>
    </student>
</students>
1
2
3
4
5
6
7
8

# Java验证xsd

使用Java通过xsd来验证xml格式是否正确:

import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

/**
 * XPath查询
 */
public class Main {

  public static boolean validateXml(String xsdPath, String xmlPath) throws SAXException, IOException {
    // 建立schema工厂
    SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
    // 建立验证文档文件对象,利用此文件对象所封装的文件进行schema验证
    File schemaFile = new File(xsdPath);
    // 利用schema工厂,接收验证文档文件对象生成Schema对象
    Schema schema = schemaFactory.newSchema(schemaFile);
    // 通过Schema产生针对于此Schema的验证器,利用schenaFile进行验证
    Validator validator = schema.newValidator();
    // 得到验证的数据源
    Source source = new StreamSource(xmlPath);
    // 开始验证,成功输出success!!!,失败输出fail
    validator.validate(source);

    return true;
  }

  public static void main(String[] args) {
    String xsdPath = Main.class.getClassLoader().getResource("student.xsd").getPath();
    String xmlPath = Main.class.getClassLoader().getResource("student.xml").getPath();

    try {
      if (validateXml(xsdPath, xmlPath)) {
        System.out.println("校验通过");
      }
    } catch (SAXException e) {
      System.out.println("校验失败");
      e.printStackTrace();
    } catch (IOException e) {
      System.out.println("校验失败");
      e.printStackTrace();
    }
  }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# Schema文档规则

  • <schema> 元素是每一个 XML Schema 的根元素。

  • xsd中元素分为:

    • 简易元素,是指那些仅包含文本的元素,不会包含任何其他元素或属性。定义简易元素的语法为:

      <xs:element name="xxx" type="yyy"/>

      • 其中可使用default设置默认值,使用fixed来设置固定值,常用的类型(type)有:
        • xs:string
        • xs:decimal
        • xs:integer
        • xs:boolean
        • xs:date
        • xs:time
    • 复合元素,是指包含其他元素或属性的XML元素,它又分为:
      • 空元素

        xml元素为:
        <product prodid="12345" />
        
        xsd定义为:
        <xs:element name="product">
          <xs:complexType>
            <xs:complexContent>
              <xs:restriction base="xs:integer">
                <xs:attribute name="prodid" type="xs:positiveInteger"/>
              </xs:restriction>
            </xs:complexContent>
          </xs:complexType>
        </xs:element>
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
      • 包含其他元素的元素

        xml元素为:
        <person>
          <firstname>li</firstname>
          <lastname>wang</lastname>
        </person>
        
        xsd定义为:
        <xs:element name="person">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="firstname" type="xs:string"/>
              <xs:element name="lastname" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
      • 仅包含文本的元素

        xml元素为:
        <area country="china">20</shoesize>
        
        xsd定义为:
        <xs:element name="area">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:integer">
                <xs:attribute name="country" type="xs:string" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
      • 包含元素和文本的元素

        xml元素为:
        <letter>
          Dear Mr.<name>xie</name>.
          Your order <orderid>1024</orderid>
          will be shipped on <shipdate>2010-01-02</shipdate>.
        </letter>
        
        xsd定义为:
        <xs:element name="letter">
          <xs:complexType mixed="true">
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="orderid" type="xs:positiveInteger"/>
              <xs:element name="shipdate" type="xs:date"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
  • xsd中的所有属性均作为简易类型来声明,简易元素无法拥有属性,如果一个元素拥有属性,它会被当作复合类型。声明方式为:

    <xs:attribute name="xxx" type="yyy"/>

  • xsd限定(Facets)用于xml元素或属性定义可接受的值:

    限定一个age元素,其值不能低于0或高于120:
    <xs:element name="age">
      <xs:simpleType>
        <xs:restriction base="xs:integer">
          <xs:minInclusive value="0"/>
          <xs:maxInclusive value="120"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:element>
    
    把xml元素的内容限制为一组可接收的值,使用枚举约束(enumeration constraint):
    <xs:element name="fruit">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="apple"/>
          <xs:enumeration value="banana"/>
          <xs:enumeration value="orange"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:element>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

# Schema解析

Schema解析有两个基本操作:

  1. 将文档中的数据读取到内存中。
  2. 将内存中的数据保存到xml文档中。

解析xml的方式有两种:

  1. DOM:将标记语言文档一次性加载进内存,在内存中形成一棵dom树。
    • 优点:操作方便,可以对文档进行CRUD的所有操作
    • 缺点:占内存
  2. SAX:逐行读取,基于事件驱动的。
    • 优点:不占内存,比较快。
    • 缺点:只能读取,不能增删改。

xml常见的解析器:

  1. JAXP(Java API for XMLProcessing):sun公司提供的解析器,支持dom和sax两种方式。
  2. DOM4J:一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
  3. Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
  4. PULL:Android操作系统内置的解析器,sax方式的。

# Jsoup入门

使用Jsoup步骤:

  1. 导入jar包
  2. 获取Document对象
  3. 获取对应的标签Element对象
  4. 获取数据

示例:

import java.io.File;


import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Main {
  public static void main(String[] args) throws Exception {
    //得到xml文件路径
        String path = Main.class.getClassLoader().getResource("student.xml").getPath();
        //解析xml文档,加载文档进内存,获取dom树--->Document
        Document document = Jsoup.parse(new File(path), "utf-8");
        //获取元素对象 Element
        Elements elements = document.getElementsByTag("name");

        System.out.println(elements.size());
        //获取第一个name的Element对象
        Element element = elements.get(0);
        //获取数据
        String name = element.text();
        System.out.println(name);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# Jsoup对象

  1. Jsoup:工具类,常使用parse方法来解析html或xml文档,返回Document。

    • parse​(File in, String charsetName):解析xml或html文件的
    • parse​(String html):解析xml或html字符串
    • parse​(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    
    
    public class Main {
        public static void main(String[] args) throws IOException {
            //1. 解析xml文档,加载文档进内存,获取dom树
            String path = Main.class.getClassLoader().getResource("student.xml").getPath();
            Document document1 = Jsoup.parse(new File(path), "utf-8");
            System.out.println(document1);
    
           //2. parse​(String html):解析xml或html字符串
            String str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                    "\n" +
                    "<students>\n" +
                    "\t<student number=\"heima_0001\">\n" +
                    "\t\t<name>tom</name>\n" +
                    "\t\t<age>18</age>\n" +
                    "\t\t<sex>male</sex>\n" +
                    "\t</student>\n" +
                    "\t<student number=\"heima_0002\">\n" +
                    "\t\t<name>jack</name>\n" +
                    "\t\t<age>18</age>\n" +
                    "\t\t<sex>female</sex>\n" +
                    "\t</student>\n" +
                    "\n" +
                    "</students>";
            Document document2 = Jsoup.parse(str);
            System.out.println(document2);
    
            //3. parse​(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
            URL url = new URL("http://www.baidu.com");//代表网络中的一个资源路径
            Document document3 = Jsoup.parse(url, 10000);
            System.out.println(document3);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
  2. Document:文档对象,代表内存中的dom树,可以获取Element对象。

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

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     * Document/Element 对象功能
     */
    public class Main {
        public static void main(String[] args) throws IOException {
            //1.获取student.xml的path
            String path = Main.class.getClassLoader().getResource("student.xml").getPath();
            //2.获取Document对象
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //3.获取元素对象了。
            //3.1获取所有student对象
            Elements elements = document.getElementsByTag("student");
            System.out.println(elements);
            System.out.println("-----------");
    
            //3.2 获取属性名为id的元素对象们
            Elements elements1 = document.getElementsByAttribute("id");
            System.out.println(elements1);
            System.out.println("-----------");
            //3.3 获取number属性值为test_0002的元素对象
            Elements elements2 = document.getElementsByAttributeValue("number", "test_0002");
            System.out.println(elements2);
            System.out.println("-----------");
    
            //3.4 获取id属性值的元素对象
            Element someObj = document.getElementById("test1");
            System.out.println(someObj);
        }
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
  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():获取标签体的所有内容(包括字标签的字符串内容)
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     *Element对象功能
     */
    public class Main {
        public static void main(String[] args) throws IOException {
            //获取student.xml的path
            String path = Main.class.getClassLoader().getResource("student.xml").getPath();
            //获取Document对象
            Document document = Jsoup.parse(new File(path), "utf-8");
            //通过Document对象获取name标签,获取所有的name标签,可以获取到两个
            Elements elements = document.getElementsByTag("name");
            System.out.println(elements.size());
            System.out.println("----------------");
            //通过Element对象获取子标签对象
            Element element_student = document.getElementsByTag("student").get(0);
            Elements ele_name = element_student.getElementsByTag("name");
            System.out.println(ele_name.size());
    
            //获取student对象的属性值
            String number = element_student.attr("NUMBER");
            System.out.println(number);
            System.out.println("------------");
            //获取文本内容
            String text = ele_name.text();
            String html = ele_name.html();
            System.out.println(text);
            System.out.println(html);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
  5. Node:节点对象,是Document和Element的父类

# Jsoup查询

Jsoup中查询元素有两种方式:

  1. selector选择器。

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     *选择器查询
     */
    public class Main {
        public static void main(String[] args) throws IOException {
            //1.获取student.xml的path
            String path = Main.class.getClassLoader().getResource("student.xml").getPath();
            //2.获取Document对象
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //3.查询name标签
            Elements elements = document.select("name");
            System.out.println(elements);
            System.out.println("=----------------");
            //4.查询id值为itcast的元素
            Elements elements1 = document.select("#test");
            System.out.println(elements1);
            System.out.println("----------------");
            //5.1.获取student标签并且number属性值为test_0001
            Elements elements2 = document.select("student[number=\"test_0001\"]");
            System.out.println(elements2);
            System.out.println("----------------");
    
            //5.2获取student标签并且number属性值为test_0001的age子标签
            Elements elements3 = document.select("student[number=\"test_0001\"] > age");
            System.out.println(elements3);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
  2. XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言,注意使用Jsoup的Xpath需要额外导入jar包,作者为JsoupXpath (opens new window)

    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;
    
    /**
     *XPath查询
     */
    public class Main {
        public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
            //1.获取student.xml的path
            String path = Main.class.getClassLoader().getResource("student.xml").getPath();
            //2.获取Document对象
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //3.根据document对象,创建JXDocument对象
            JXDocument jxDocument = new JXDocument(document);
    
            //4.结合xpath语法查询
            //4.1查询所有student标签
            List<JXNode> jxNodes = jxDocument.selN("//student");
            for (JXNode jxNode : jxNodes) {
                System.out.println(jxNode);
            }
    
            System.out.println("--------------------");
    
            //4.2查询所有student标签下的name标签
            List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
            for (JXNode jxNode : jxNodes2) {
                System.out.println(jxNode);
            }
    
            System.out.println("--------------------");
    
            //4.3查询student标签下带有id属性的name标签
            List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
            for (JXNode jxNode : jxNodes3) {
                System.out.println(jxNode);
            }
            System.out.println("--------------------");
            //4.4查询student标签下带有id属性的name标签 并且id属性值为itcast
    
            List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='test']");
            for (JXNode jxNode : jxNodes4) {
                System.out.println(jxNode);
            }
        }
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55