3.1_20 JavaSE入门 P19 【xml】CDATA、约束(dtd,schema)、解析(dom,sax)、Jsoup(爬虫)、selector、Xpath

相关链接



All From 传智培训课程 + 后期自己整理补充内容


P19 【xml】CDATA、约束(dtd,schema)、解析(dom,sax)、Jsoup(爬虫)、selector、Xpath


  • 今日要掌握的内容:
    • 【理解】理解xml文件的作用
    • 【应用】掌握xml文件的组成部分及如何编写
    • 【理解】理解xml的两种约束格式
    • 【应用】理解xml两种解析方式的原理
    • 【应用】掌握Jsoup的常用方法

1 xml


1.1 xml概述


1.概念: xml语言是可扩展的标记语言eXtensible Markup Language),它被设计的宗旨是描述数据,而非显示数据

  可扩展:标签都是自定义的 <user> <student>

  xml设计之初用来代替html,失败后用来代替properties

2.作用:用来存储数据。(a.存储一对多的数据关系、b.当做配置文件存储数据、c.在网络中传输)

3.xml与html的区别:

  a. xml使用自定义标签 。 HTML需要使用预定义标签

  b. xml的语法严格,html语法松散

  c.xml是存储数据的,html是展示数据的

<!--properties实现存储-->
name=zhangsan
age=23
gender=nan

name=lisi
age=24
gender=nv

<!--xml实现存储-->
<users>
    <user id='1'>
        <name>zhangsan</name>
        <age>23</age>
        <gender>nan</gender>
    </user>
    <user id='2'>
        <name>lisi</name>
        <age>24</age>
        <gender>nv</gender>
    </user>
</users>

XML技术是W3C组织(World Wide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。

XML被广泛认为是继Java之后在Internet上最激动人心的新技术。

  举例:

1
2
3
4
5
6
中国
北京
山东
湖北
海淀
丰台
济南
青岛
武汉
荆州

  通过xml实现存储:

<?xml version='1.0' encoding='UTF-8' ?>
<中国>
	<北京>
        <海淀>1</海淀>
        <丰台>2</丰台>
	</北京>
	<山东>
        <济南>3</济南>
        <青岛>4</青岛>
	</山东>
	<湖北>
        <武汉>5</武汉>
        <荆州>6</荆州>
	</湖北>
</中国>

  以上这种数据,如果通过我们学习的集合来存储的话, 需要通过多个集合的嵌套使用。那么很显然, 数据存储的过程就非常麻烦, 今天所学习的xml文件就可以实现 => 存储一对多的数据

  另外, xml还有一些其他的应用方面:

  之前学习过properties配置文件, 通过这种配置文件, 可以使代码的编写更加灵活。但是这种配置文件也只能存储一个键值对的映射关系, 如果需要存储多个呢?没错, 可以使用xml , 所以xml的另一方面应用就展示出来了 => 用来当做配置文件存储数据


xml技术用于解决什么问题

  xml语言出现的根本目的在于描述像上图出现的那种有关系的数据。

  xml是一种通用的数据交换格式。

  xml语言中,允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在起始标签之间,又可以使用其他标签描述其他数据,一次来实现数据关系的描述。

  xml中的数据必须通过软件程序来解析执行或显示,如IE;这样的解析程序称之为Parser(解析器)


xml常见应用

  在Java开发中,传统的配置文件是*.properties属性文件(key=value),而xml标示的数据更为丰富。

  xml技术除用于描述有关的数据外,还经常用作软件配置文件,以描述程序模块之间的关系。(Struts、Spring、Hibernate框架都是基于XML作为配置文件的)

  在一个软件系统中,通过xml配置文件可以提高系统的灵活性。即程序的行为是通过xml文件来配制的,而不是硬编码


xml是怎样存储数据的?

  答: 以标签的形式存储

  例: <name>Java<name>


1.2 xml语法


基本语法

  1. xml 文档后缀名.xml

  2. xml第一行必须定义文档声明

  3. xml 有且只有一个根标签

  4. 元素的属性值必须使用引号(单双都可)引起来

  5. 标签必须正确关闭 => <name>a</name> 或自闭和标签<br/>

  6. xml标签名区分大小写


1.3 xml组成部分


1.3.1 文档声明

 * 在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行

   a.格式:<?xml 属性列表 ?>

   b.属性列表:

     * version:版本号,必填

     * encoding:编码方式,告知解析引擎,当前文档使用的字符集;默认:IOS-8859-1;选填

     * standalone:是否独立,一般省略不填;选填

       * 取值:

         * yes:不依赖其他文件

         * no:依赖其他文件

<?xml version="1.0" encoding="utf-8" standalone='yes' ?>

<users></users>

1.3.2 指令(了解)

 * 案例需求:xml引用css样式,所有name标签渲染字体为红色

   * xml文件

   * xml文件

<?xml version="1.0" encoding="utf-8" standalone='yes' ?>
<?xml-stylesheet type="text/css" href="a.css" ?>

<users></users>

   * css文件

name{
    color:red
}

1.3.3 标签

   * 概念:xml的元素叫做标签,标签名称是自定义的

   * 规则:

     1. 名称可以包含字母、数字以及其他字符

     2.名称不能以数字或标点符号开始

     3. 名称不能以字母 xml(或者XML、Xml 等等)开始

     4.名称不能包含空格、制表符

     5. 严格区分大小写;<p>与<P>

     6. 名称字符之间不能使用冒号 : (有特殊用途)

   * 分类:

      包含标签体 尖括号全部成对出现,所有数据用一对尖括号存储

        <student>
            <name>zhangsan</name>
            <age>18</age>
        </student>

     不包含标签体 只有最外层的一个尖括号,括号用/标识结束,内部的数据都用属性来编写

        <student 
            name='zhangsan'
            age='18'
        />

1.3.4 属性

 * 1. 一个元素可以有多个属性,每个属性都有它自己的名称(K)和取值(V)。

 * 2. 属性值一定要用引号(单引号或双引号)引起来。

 * 3. 属性名称的命名规范与元素的命名规范相同

 * 4. 元素中的属性不允许重复

 * 5. 在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述

<?xml version='1.0' encoding='UTF-8'?>
<students>
	<student name='zhangsan' age='18' />
    
    <!-- 在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述 -->
	<student>
		<name>zhangsan</name>
		<age>18</age>
	</student>
</students>

1.3.5 文本 CDATA区

  详见1.4

  * CADATA区:在该区域中的数据会被原样展示

    * 格式:<![CDATA[ 数据 ]]>


1.3.6 注释

	<!--注释内容-->

1.3.7 PI

处理指令(PI:Processing Instruction)


1.4 xml特殊符号处理


1.4.1 CDATA区

为什么要使用CDATA区?

  如果我们在标签中写入的内容,想要带有标签的标记符号的话,就需要对这段内容进行转义。

  就好比java中的打印语句,想要打印出”这个字符就必须用\进行转义。

  标签也是一样,想要将<itheima>当做内容存储的话,就需要对他进行转义。

  <![CDATA[ ... ]]>


如何转义?

特殊字符替代符号
&&amp;
<&lt;
>&gt;
"&quot;
&apos;

注意:

  这种转义可以达到效果,但是如果操作的数据过多,编写起来会非常痛苦,所以,可以使用CDATA区来解决此问题。


1.4.2 CDATA示例

案例代码一xml特殊符号的处理

<?xml version='1.0' encoding='UTF-8'?>
<!--
    @introduction xml特殊符号处理
	如果有一个包含标签体的标签,
	他的标签体是一个普通文本,不是子标签,
	而普通文本中包含了一个标签,那这样可以吗?

	xml特殊符号有两种实现方式
	    1.CDATA区
	    2.转义
-->

<students>
    <student>
        <name>zhangsan</name>
        <!--1.CDATA区方式-->
        <url>
            <![CDATA[
				<itheima>www.itheima.com</itheima>
				<itcast>www.itcast.cn</itcast>
			]]>
        </url>
    </student>


    <student>
        <name>zhangsan</name>
        <!--2.转义方式-->
        <url>
            &lt;itheima&gt;www.itheima.com&lt;/itheima&gt;
        </url>
    </student>
</students>

1.5 xml约束


1.5.1 xml约束概述

约束: 规定xml文档的书写规则

  * 作为框架的使用者(程序员)

    1. 能够在xml中引入约束文档

    2. 能够简单读懂约束文档(IDEA也会给出智能提示)

  * 分类

    1. DTD:一种简单的约束技术

    2. Schema:一种复杂的约束技术

  * DTD:

    * 引入dtd文档到xml文档中

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

      * b. 外部dtd:将约束规则定义外部的dtd文件中

        * 本地:<!DOCTYPE 根标签名称 SYSTEM "dtd文件的位置"

        * 网络:<!DOCTYPE 根标签名称 PUBLIC "dtd文件名字" "dtd文件的位置URL"


1.5.2 xml约束-dtd

1.5.2.1 外部DTD(本地)

DTD约束文档  student.dtd

<!ELEMENT students (student*)>
        <!ELEMENT student (name,age,gender)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT gender (#PCDATA)>
        <!ATTLIST student number ID #REQUIRED>

XML文档(外部引入DTD)  student.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="ccc">
        <name>lisi</name>
        <age>24</age>
        <gender>female</gender>
    </student>
</students>

DTD约束文档说明  student.dtd

 <!--声明一个标签,标签名称为students-->
 <!--students可以存放student子标签-->
 <!--量词符号*表示student可以出现0次或多次,如果是+则表示1次或多次-->
 <!ELEMENT students (student*)>

 	<!--student标签可以出现 name age gender三种子标签,各个子标签需要按顺序出现-->
 	<!--没有量词符号表示各个子标签只能出现一次-->
 	<!ELEMENT student (name,age,gender)>

	<!--#PCDATA 表示数据内容是字符串-->
	<!ELEMENT name (#PCDATA)>
	<!ELEMENT age (#PCDATA)>
	<!ELEMENT gender (#PCDATA)>

	<!--ATTLIST 表示student标签有属性,属性名字为number-->
 	<!--ID 表示number属性必须唯一,且非空-->
 	<!--#REQUIRED 表示number属性必须出现-->
	<!ATTLIST student number ID #REQUIRED>

XML文档(如何引入路径的)

在这里插入图片描述


1.5.2.1 内部DTD(本地)

XML文档(内部引入DTD) student.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE students [
        <!ELEMENT students (student+)>
        <!ELEMENT student (name,age,gender)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT gender (#PCDATA)>
        <!ATTLIST student number ID #REQUIRED>
]>
<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="ccc">
        <name>lisi</name>
        <age>24</age>
        <gender>female</gender>
    </student>
</students>

1.5.3 xml约束-shcema(.xsd)

XML文档(使用空前缀)  student.xml

<?xml version="1.0" ?>
<xsd:schema xmlns="http://www.itcast.cn/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.itcast.cn/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="gender" type="genderType"/>
        </xsd:sequence>
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="genderType">
        <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:maxExclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="heima_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

XML文档(使用前缀)  student2.xml

<?xml version="1.0" ?>
<!--使用前缀的方式,这种方式可以引用多个约束
    空前缀和使用前缀两种方式可以同时使用

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

-->
<a:students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.itcast.cn/xml  student2.xsd"
          xmlns:a="http://www.itcast.cn/xml"
            >
    <!--<student number="abc"> 报错-->
    <a:student number="heima_0001">
        <a:name>zhangsan</a:name>
        <a:age>23</a:age>
        <!--<gender>nan</gender> 报错-->
        <a:gender>male</a:gender>
    </a:student>
    <a:student number="heima_0002">
        <a:name>lisi</a:name>
        <a:age>11</a:age>
        <a:gender>female</a:gender>
    </a:student>
</a:students>

schema约束文档  student.xsd

<?xml version="1.0" ?>
<xsd:schema xmlns="http://www.itcast.cn/xml"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.itcast.cn/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="gender" type="genderType"/>
        </xsd:sequence>
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="genderType">
        <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:maxExclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="heima_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

schema约束文档说明  student.xsd

<?xml version="1.0" ?>
<xsd:schema xmlns="http://www.itcast.cn/xml"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified">
        <xsd:element name="students" type="studentsType"/>
        <xsd:complexType name="studentsType">
            <!--sequence:按顺序出现student元素-->
            <xsd:sequence>
                <!--type:studentType student元素类型为 studentType类型-->
                <!--minOccurs=“0”  最少出现0次-->
                <!--maxOccurs="unbounded"  最多出现无数次-->
                <xsd:element name="student" type="studentType" minOccurs="0"  maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    <xsd:complexType name="studentType">
        <!--sequence 按name,age,gender顺序出现student属性-->
        <xsd:sequence>
            <!--xsd:string 字符串类型-->
            <xsd:element name="name" type="xsd:string"/>
            <!--type="ageType" 自定义类型,在下方 <xsd:simpleType name="ageType"> 中有详细定义-->
            <xsd:element name="age" type="ageType"/>
            <!--type="genderType" 自定义类型,在下方 <xsd:simpleType name="genderType"> 中有详细定义-->
            <xsd:element name="gender" type="genderType"/>
        </xsd:sequence>
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="genderType">
        <!--restriction 元素定义对 simpleType、simpleContent 或 complexContent 定义的约束。-->
        <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:maxExclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <!--numberType数据格式: heima_四位数字-->
            <xsd:pattern value="heima_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

2 解析xml文件


解析: 操作xml文档,将文档中的数据读取到内存中

  * 操作xml文档

    * 1. 解析(读取):将文档中的数据读取到内存中

    * 2. 写入:将内存中的数据保存到xml文档中。持久化的存储


2.1 XML解析(2种方式)


  * 解析xml的方式

    * 1. DOM:将标记语言文档一次性加载进内存,在内存中会形成一颗dom树

      * 优点:操作方便,可以对文档进行CURD的所有操作

      * 缺点:比较占内存

在这里插入图片描述

    * 2. SAX:逐行读取,基于事件驱动的。

      * 优点:不占内存,适用小内存设备,比如:手机

      * 缺点:只能读取,不能增删改;且代码编写难度会更大(需要判断各种标签的处理逻辑)。


2.2 xml常见的解析器


  * 1. JAXP:sun公司提供的解析器,支持dom和sax两种思想。(官方提供,性能低,代码复杂,基本没人用)

  * 2. DOM4J:一款非常优秀的解析器,支持dom,sax和jaxp。

  * 3. Jsoup:是HTML解析器,可直接解析某个URL地址、HTML文本内容。可通过dom,css以及类似于jQuery的操作方法操作数据。

  * 4. PULL:Android操作系统内置的解析器,sax方式。


3 Jsoup(可用于爬虫)


3.1 Jsoup快速入门


  * 步骤

    1. 导入jar包(pom.xml中添加依赖)

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.2</version>
        </dependency>

    2. 获取Document对象

    3. 获取对应的标签Element对象

    4. 获取数据


案例代码四Jsoup快速入门  【student.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name>zhangSan</name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name>liSi</name>
        <age>11</age>
        <gender>female</gender>
    </student>
</students>

案例代码四Jsoup快速入门  【测试类】

package com.groupies.base.day19.Demo04;

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;
import java.net.URL;

/**
 * @author GroupiesM
 * @date 2021/06/16
 * @introduction Jsoup快速入门
 *
 * 步骤
 *
 *  1. 导入jar包(pom.xml中添加依赖)
 *         <dependency>
 *             <groupId>org.jsoup</groupId>
 *             <artifactId>jsoup</artifactId>
 *             <version>1.11.2</version>
 *         </dependency>
 *  2. 获取Document对象
 *      2.1 根据xml文档获取
 *      2.2
 *      2.3
 *  3. 获取对应的标签Element对象
 *  4. 获取数据
 */
public class JsoupLearn {
    public static void main(String[] args) throws IOException {
        //2.1 获取Document对象(根据xml文档获取)
        //2.1.1 获取student.xml的path
        ClassLoader classLoader = JsoupLearn.class.getClassLoader();
        URL resource = classLoader.getResource("student.xml");
        String path = resource.getPath();

        //2.1.2 解析xml文档,加载文档进内存,获取dom树--->Document对象 (编码方式要和student.xml编码一致)
        Document document = Jsoup.parse(new File(path), "utf-8");
        //3 获取元素对象
        /* Elements父类
           Elements extends ArrayList<Element>
        */
        Elements nameList = document.getElementsByTag("name");
        System.out.println(nameList.size());
        //3.1 获取第一个name的Element对象
        Element element = nameList.get(0);
        /*
            <name>
             zhangSan
            </name>
         */
        System.out.println(element);
        //3.2获取数据
        String name = element.text();
        System.out.println(name);//zhangSan
    }
}

3.2 Jsou对象


  * 对象的使用

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

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

        * parse(File in,String charsetName):解析xml或html文件的

        * parse(String html):解析xml或html字符串

        * parse(URL url,int timeoutMillis): 通过网络路径获取指定的htmlo或xml文档对象,可用于爬虫

    * 2. Document:文档对象。代表内存中的dom树;(Document extends Element)

      * 2.1 返回Elements

        * getElementsByTag(String tagName):根据标签名称获取元素集合

        * getElementsByAttribute(String key):根据属性名称获取元素对象集合

        * getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值获取元素对象集合

      * 2.2 返回Element

        * getElementsById(String id):根据id属性值获取惟一的元素对象

         (xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)

    * 3. Elements:元素Element对象的集合。可以当做ArrayList<Element>来使用(Element extends Node);

    * 4. Element:元素对象;

      * 4.1返回子标签Element

        * getElementsById(String id):根据id属性值获取惟一的子标签元素对象

         (xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)

      * 4.2 返回子标签Elements

        * getElementsByTag(String tagName):根据标签名称获取子标签元素对象集合

        * getElementsByAttribute(String key):根据属性名称获取子标签元素对象集合

        * getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值获取子标签元素对象集合

      * 4.3 返回String

        * attr(String key):根据属性名称获取属性值

        * text():获取子标签的纯文本内容

        * html():获取标签体的所有内容(包括子标签的标签和文本内容)

      * 4.3 修改属性值

    * 5. Node:节点对象,是Document和Element的父类;

      * 返回Node

        * childNode(int index):返回指定索引的子节点对象

      * 返回ListNode

        * childNodes():返回所有子节点对象

      * 返回boolean

        *hasAttr(String attributeKey):判断元素有没有属性

      * 无返回值

        *remove():从dom树删除此节点


3.2.1 Jsoup 工具类

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

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

     * parse(File in,String charsetName):解析xml或html文件的

     * parse(String html):解析xml或html字符串

     * parse(URL url,int timeoutMillis): 通过网络路径获取指定的htmlo或xml文档对象,可用于爬虫


  • 静态成员方法
 //方式1 解析xml或html文件的
 parse(File in,String charsetName)
 
 //方式2 解析xml或html字符串
 parse(String html)
  
 //方式3 通过网络路径获取指定的htmlo或xml文档对象,可用于爬虫
 parse(URL url,int timeoutMillis)

案例代码五Jsoup工具类  【student.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name>zhangSan</name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name>liSi</name>
        <age>11</age>
        <gender>female</gender>
    </student>
</students>

案例代码五Jsoup工具类  【测试类】

package com.groupies.base.day19.Demo05;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * @author GroupiesM
 * @date 2021/06/16
 * @introduction Jsoup工具类
 *
 *  //方式1 解析xml或html文件的
 *  parse(File in,String charsetName)
 *
 *  //方式2 解析xml或html字符串
 *  parse(String html)
 *  
 *  //方式3 通过网络路径获取指定的htmlo或xml文档对象,可用于爬虫
 *  parse(URL url,int timeoutMillis)
 */
public class JsoupObject {
    public static void main(String[] args) throws IOException {
        //获取student.xml的path
        ClassLoader classLoader = JsoupObject.class.getClassLoader();
        URL resource = classLoader.getResource("student.xml");
        String path = resource.getPath();

        //方式1:parse(File in,String charsetName):解析xml或html文件的
        // 加载文档进内存,获取dom树---> Document对象 (编码方式要和student.xml编码一致)
        Document document1 = Jsoup.parse(new File(path), "utf-8");
        /*
            <!--?xml version="1.0" ?-->
            <html>
             <head></head>
             <body>
              <students>
               <student number="heima_0001">
                <name>
                 zhangSan
                </name>
                <age>
                 23
                </age>
                <gender>
                 male
                </gender>
               </student>
               <student number="heima_0002">
                <name>
                 liSi
                </name>
                <age>
                 11
                </age>
                <gender>
                 female
                </gender>
               </student>
              </students>
             </body>
            </html>
         */
        System.out.println(document1);
        System.out.println("===================");

        //方式2:parse(String html):解析xml或html字符串
        Document document2 = Jsoup.parse("<?xml version=\"1.0\" ?>\n" +
                                             "<students>\n" +
                                             "    <student number=\"heima_0001\">\n" +
                                             "        <name>zhangSan</name>\n" +
                                             "        <age>23</age>\n" +
                                             "        <gender>male</gender>\n" +
                                             "    </student>\n" +
                                             "    <student number=\"heima_0002\">\n" +
                                             "        <name>liSi</name>\n" +
                                             "        <age>11</age>\n" +
                                             "        <gender>female</gender>\n" +
                                             "    </student>\n" +
                                             "</students>");
        //同上
        System.out.println(document2);
        System.out.println("===================");

        //方式3:parse(URL url,int timeoutMillis): 通过网络路径获取指定的htmlo或xml文档对象
        URL url = new URL("https://baike.baidu.com/item/jsoup/9012509");//代表网络中的一个资源路径
        Document document3 = Jsoup.parse(url, 10000);
        /*
            <!doctype html>
            <!--STATUS OK-->
            <html>
             <head>
              <meta charset="UTF-8">
              <meta http-equiv="X-UA-Compatible" content="IE=Edge">
              <meta name="referrer" content="always">
              <meta name="description" content="jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。...">
              <title>jsoup_百度百科</title>
              ......略
         */
        System.out.println(document3);
    }
}

3.2.2 Document 文档对象(dom树对象)

 * 2. Document:文档对象。代表内存中的dom树;(Document extends Element)

   * 2.1 返回Element

     * getElementsById(String id):根据id属性值获取惟一的元素对象

      (xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)

   * 2.2 返回Elements

     * getElementsByTag(String tagName):根据标签名称获取元素集合

     * getElementsByAttribute(String key):根据属性名称获取元素对象集合

     * getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值获取元素对象集合


案例代码六Document文档对象  【student2.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name id="itcast">zhangSan</name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name>liSi</name>
        <age>11</age>
        <gender>female</gender>
    </student>
</students>

案例代码六Document文档对象 【测试类】

package com.groupies.base.day19.Demo07;

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;
import java.net.URL;

/**
 * @author GroupiesM
 * @date 2021/06/16
 * @introduction Element文档对象
 *
 *  2. Document:文档对象。代表内存中的dom树;(Document extends Element)
 *
 *  返回Element
 *      //方式1:根据id属性值获取惟一的元素对象(xml中不常用,在html中id是预定义标签,表示主键)
 *      getElementsById(String id)
 *          
 * 返回Elements
 *      //方式2:根据标签名称获取元素集合
 *      getElementsByTag(String tagName)
 *
 *      //方式3:根据属性名称获取元素对象集合
 *      getElementsByAttribute(String key)
 *
 *      //方式4:根据对应的属性名和属性值获取元素对象集合
 *      getElementsByAttributeValue(String key,String value)
 */
public class JsoupObjectElement {
    public static void main(String[] args) throws IOException {
        //获取student.xml的path
        ClassLoader classLoader = JsoupObjectElement.class.getClassLoader();
        URL resource = classLoader.getResource("student2.xml");
        String path = resource.getPath();

        //获取Document对象
        Document document = Jsoup.parse(new File(path), "utf-8");

        //1.获取元素对象
        //1.1 获取id为为itcast的对象集合
        //方式1:getElementsById(String id) 根据id属性值获取惟一的元素对象(xml中不常用,在html中id是预定义标签,表示主键)
        Element element1 = document.getElementById("itcast");
        /* zhangSan */
        System.out.println(element1.text());
        System.out.println("===================");

        //1.2 获取所有Student对象
        //方式2:getElementsByTag(String tagName) 根据标签名称获取元素集合
        Elements element2 = document.getElementsByTag("student");
        for (Element element : element2) {
            /*zhangSan 23 male
              liSi 11 female*/
            System.out.println(element.text());
        }
        System.out.println("===================");

        //1.3 获取属性名为id的元素对象集合
        //方式3:getElementsByAttribute(String key) 根据属性名称获取元素对象集合
        Elements element3 =  document.getElementsByAttribute("id");
        for (Element element : element3) {
            /* zhangSan */
            System.out.println(element.text());
        }
        System.out.println("===================");

        //1.4 获取number属性值为heima_0001的元素对象
        //方式4:getElementsByAttributeValue(String key,String value) 根据对应的属性名和属性值获取元素对象集合
        Elements element4 = document.getElementsByAttributeValue("number", "heima_0001");
        for (Element element : element4) {
            /* zhangSan 23 male */
            System.out.println(element.text());
        }
    }
}

3.2.3 Elements 元素对象集合

Elements extends ArrayList<Element>

 * 3. Elements:元素Element对象的集合。可以当做ArrayList<Element>来使用(Element extends Node);


3.2.4 Element 元素对象

 * 4. Element:元素对象;

   * 4.1 返回子标签Elements

     * getElementsByTag(String tagName):根据标签名称获取子标签元素对象集合

     * getElementsByAttribute(String key):根据属性名称获取子标签元素对象集合

     * getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值获取子标签元素对象集合

   * 4.2 返回子标签Element

     * getElementsById(String id):根据id属性值获取惟一的子标签元素对象

      (xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)

   * 4.3 返回String

     * attr(String key):根据属性名称获取属性值

     * text():获取所有子标签的纯文本内容

     * html():获取标签体的所有内容(包括子标签的标签和文本内容)

   * 4.4 修改属性值


案例代码七Element元素对象  【student3.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name id="itcast" class="5">
            <firstName></firstName>
            <secondName></secondName>
        </name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name id="itheima">liSi</name>
        <age>11</age>
        <gender class="6">female</gender>
    </student>
</students>

案例代码七Element元素对象 【测试类】

package com.groupies.base.day19.Demo07;

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;
import java.net.URL;

/**
* @author GroupiesM
* @date 2021/06/16
* @introduction Element元素对象
*
*  4.1 返回子标签Elements
*      //方式1 根据标签名称获取子标签元素对象
*      getElementsByTag(String tagName)
*
*      //方式2 根据属性名称获取子标签元素对象
*      getElementsByAttribute(String key)
*
*      //方式3 根据对应的属性名和属性值获取子标签元素对象
*      getElementsByAttributeValue(String key,String value)
*
*  4.2 返回子标签Element
*      //方式4 根据id属性值获取惟一的子标签元素对象(xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)
*      getElementsById(String id):
*
*  4.3 返回String
*      //方式5 根据属性名称获取属性值
*      attr(String key)
*
*      //方式6 获取所有子标签的纯文本内容
*      text()
*
*      //方式7 获取标签体的所有内容(包括子标签的标签和文本内容)
*      html()
*/
public class JsoupObjectElement {
   public static void main(String[] args) throws IOException {
       //获取student.xml的path
       ClassLoader classLoader = JsoupObjectElement.class.getClassLoader();
       URL resource = classLoader.getResource("student3.xml");
       String path = resource.getPath();

       //获取Document对象
       Document document = Jsoup.parse(new File(path), "utf-8");

       Element element_0 = document.getElementsByTag("name").get(0);
       Element element_1 = document.getElementsByTag("name").get(1);



       //获取name标签
       //通过Document对象获取name标签,获取所有的name标签,可以获取到2个
       Elements elements = document.getElementsByTag("name");
       /* 2 */
       System.out.println(elements.size());
       System.out.println("elements===================");

       //方式1 getElementsByTag(String tagName) 根据标签名称获取子标签元素对象集合
       Elements element_0_2 = element_0.getElementsByTag("name");
       Elements element_1_2 = element_1.getElementsByTag("name");
       /* 1 */
       System.out.println(element_0_2.size());
       System.out.println("element_0_2===================");
       /* 1 */
       System.out.println(element_1_2.size());
       System.out.println("element_1_2===================");

       //方式2 getElementsByAttribute(String key) 根据属性名称获取子标签元素对象集合
       Elements element_0_3 = element_0.getElementsByAttribute("id");
       Elements element_1_3 = element_1.getElementsByAttribute("id");
       /* 张 三 */
       System.out.println(element_0_3.text());
       System.out.println("element_0_3===================");
       /* lisi */
       System.out.println(element_1_3.text());
       System.out.println("element_1_3===================");

       //方式3 getElementsByAttributeValue(String key,String value) 根据对应的属性名和属性值获取子标签元素对象集合
       Elements element_0_4 = element_0.getElementsByAttributeValue("class", "5");
       Elements element_1_4 = element_1.getElementsByAttributeValue("class", "6");
       /* 张 三 */
       System.out.println(element_0_4.text());
       System.out.println("element_0_4===================");
       /* */
       System.out.println(element_1_4.text());
       System.out.println("element_1_4===================");

       //方式4 getElementsById(String id) 根据id属性值获取惟一的子标签元素对象(xml中不常用此方法,xml可以自定义标签。在html中id是预定义标签,表示主键)
       Element element_0_1 = element_0.getElementById("itcast");
       Element element_1_1 = element_1.getElementById("itcast");
       /* 张 三 */
       System.out.println(element_0_1.text());
       System.out.println("element_0_1===================");
       /* null */
       System.out.println(element_1_1);
       System.out.println("element_1_1===================");

       //方式5 attr(String key) 根据属性名称获取属性值(不区分大小写)
       String str_0_5 = element_0.attr("ID");
       String str_1_5 = element_1.attr("ID");
       /* itcast */
       System.out.println(str_0_5);
       System.out.println("str_0_5===================");
       /* itheima */
       System.out.println(str_1_5);
       System.out.println("str_1_5===================");


       //方式6 text() 获取文本内容
       String str_0_6 = element_0.text();
       String str_1_6 = element_1.text();
       /* 张 三 */
       System.out.println(str_0_6);
       System.out.println("str_0_6===================");
       /* liSi */
       System.out.println(str_1_6);
       System.out.println("str_1_6===================");

       //方式7 html() 获取标签体的所有内容(包括自定义子标签字符串内容)
       String str_0_7 = element_0.html();
       String str_1_7 = element_1.html();

       /* <firstname>
          张
         </firstname>
         <secondname>
          三
         </secondname> */
       System.out.println(str_0_7);
       System.out.println("str_0_7===================");
       /* liSi */
       System.out.println(str_1_7);
       System.out.println("str_1_7===================");
   }
}

3.2.5 Node 节点对象

 * 5. Node:节点对象,是Document和Element的父类;

   * 返回Node

     * childNode(int index):返回指定索引的子节点对象

   * 返回ListNode

     * childNodes():返回所有子节点对象

   * 返回boolean

     *hasAttr(String attributeKey):判断元素有没有属性

   * 无返回值

     *remove():从dom树删除此节点

 Node对象不常用,了解即可


3.3 快速查询方式


如果想获取【张】=> 需要获取student标签 下的name标签下的firstName标签下的内容,比较麻烦

String path = JsoupObjectElement1.class.getClassLoader().getResource("student3.xml").getPath();;
Document document = Jsoup.parse(new File(path), "utf-8");
Elements student = document.getElementsByTag("student");
Elements name = student.get(0).getElementsByTag("name");
Elements firstName = name.get(0).getElementsByTag("firstName");
System.out.println(firstName.text());//张

在这里插入图片描述

现在有更快速的查询方式

 * 快速查询方式

   * 1. selector:选择器

   学习 => Jsoup的select选择器语法

     * 所在类:Element、Document(Element子类)

     * 返回值:Elements

     * 使用的方法:select(String cssQuery)

     * 参数cssQuery:css选择器

     * 语法:参考Selector类中定义的语法

   * 2. Xpath:路径语言

   学习 => W3school_Xpath

     * 2.1 使用Jsoup的Xpath需要额外导入jar包 maven

<dependency>
    <groupId>cn.wanghaomiao</groupId>
    <artifactId>JsoupXpath</artifactId>
    <version>2.3.2</version>
</dependency>

     * 2.2 构造方法

       JXDocument jxDocument = new JXDocument(document);

     * 2.3 成员方法

       * Object selOne(String xpath)

       * List sel(String xpath)

       * List selN(String xpath)

       * JXNode selNOne(String xpath)


3.3.1 selector选择器

概述:

   jsoup elements对象支持类似于CSS(或jquery)的选择器语法,来实现非常强大和灵活的查找功能。

   这个select 方法在Document, Element,或Elements对象中都可以使用。且是上下文相关的,因此可实现指定元素的过滤,或者链式选择访问。

   Select方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。

   学习 => Jsoup的select选择器语法


 * selector:选择器

   * 所在类:Element、Document(Element子类)

   * 返回值:Elements

   * 使用的方法:select(String cssQuery)

   * 参数cssQuery:css选择器

   * 语法:参考Selector类中定义的语法


案例代码八快速查询方式1-selector选择器  【student3.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name id="itcast" class="5">
            <firstName></firstName>
            <secondName></secondName>
        </name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name id="itheima">liSi</name>
        <age>11</age>
        <gender class="6">female</gender>
    </student>
</students>

案例代码八快速查询方式1-selector选择器 【测试类】

package com.groupies.base.day19.Demo08;

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

import java.io.File;
import java.io.IOException;

/**
 * @author GroupiesM
 * @date 2021/06/16
 * @introduction 快速查询方式1-selector选择器
 */
public class JsoupSelector {
    public static void main(String[] args) throws IOException {
        //获取student.xml的path
        String path = JsoupElementSelector.class.getClassLoader().getResource("student3.xml").getPath();

        //获取Document对象
        Document document = Jsoup.parse(new File(path), "utf-8");

        //1.查询name标签
        /* css选择器
            div{

            }
         */
        Elements elements1 = document.select("name");
        /* 张 三 liSi */
        System.out.println(elements1.text());
        System.out.println("===================");

        //2.查询id值为itcast的元素
        Elements elements2 = document.select("#itcast");
        /* 张 三 */
        System.out.println(elements2.text());
        System.out.println("===================");

        //3.获取number=heima_0001的student下的age标签的值
        //3.1 获取number=heima_0001的student
        Elements element3_1 = document.select("student[number='heima_0001']");
        /* 张 三 23 male */
        System.out.println(element3_1.text());
        System.out.println("===================");

        //3.2 获取student下的age标签的值
        Elements element3_2 = element3_1.select("age");
        /* 23 */
        System.out.println(element3_2.text());
        System.out.println("===================");

        //3.2 直接获取student下的age标签的值
        Elements element3_3 = document.select("student[number='heima_0001'] > age");
        /* 23 */
        System.out.println(element3_3.text());
        System.out.println("===================");
    }
}

3.3.1 Xpath路径语言

概述:

   XPath 是一门在 XML 文档中查找信息的路径语言。

   XPath 可用来在 XML 文档中对元素和属性进行遍历,确定XML文档中某部分位置。

   XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。因此,对 XPath 的理解是很多高级 XML 应用的基础。

   学习 => W3school_Xpath


案例代码九快速查询方式1-Xpath路径语言  【student3.xml】

maven项目放到resources目录下,普通java项目直接放到src目录下

在这里插入图片描述

<?xml version="1.0" ?>
<students>
    <student number="heima_0001">
        <name id="itcast" class="5">
            <firstName></firstName>
            <secondName></secondName>
        </name>
        <age>23</age>
        <gender>male</gender>
    </student>
    <student number="heima_0002">
        <name id="itheima">liSi</name>
        <age>11</age>
        <gender class="6">female</gender>
    </student>
</students>

案例代码九快速查询方式1-Xpath路径语言 【测试类】

package com.groupies.base.day19.Demo09;

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;

/**
 * @author GroupiesM
 * @date 2021/06/16
 * @introduction 快速查询方式2-Xpath路径语言
 */
public class JsoupXpath {
    public static void main(String[] args) throws IOException {
        //获取student.xml的path
        String path = JsoupXpath.class.getClassLoader().getResource("student3.xml").getPath();

        //获取Document对象
        Document document = Jsoup.parse(new File(path), "utf-8");

        //1.根据document对象创建JXDocument对象
        JXDocument jxDocument = new JXDocument(document);

        //2.结合xpath语法查询
        //2.1 查询所有student标签
        List<JXNode> jxNodes1 = jxDocument.selN("//student");
        for (JXNode jxNode : jxNodes1) {
            /*
                张 三 23 male
                liSi 11 female
             */
            System.out.println(jxNode.getElement().text());
        }
        System.out.println("========================");
        //2.2 查询所有student标签下的name标签
        List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
        for (JXNode jxNode : jxNodes2) {
            System.out.println(jxNode.getElement().text());
        }
        System.out.println("========================");

        //2.3 查询student标签下带有class属性的name标签
        List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@class]");
        for (JXNode jxNode : jxNodes3) {
            /* 张 三 */
            System.out.println(jxNode.getElement().text());
        }
        System.out.println("========================");

        //2.4 查询student标签下带有id属性的name标签,且id属性值为itheima
        List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='itheima']");
        for (JXNode jxNode : jxNodes4) {
            /* liSi */
            System.out.println(jxNode.getElement().text());
        }
        System.out.println("========================");
    }
}

4 Dom4J


 略 ,与Jsoup功能类似,会一种即可


21/06/18

M

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值