XML与Jsoup

1. XML概述

1.1 XML的概念

  • HTML:Hyper Text Markup Language 超文本标记语言,由各种标签组成。
  • XML: eXtensible Markup Language 可扩展标记语言

名词解释:

  • 可拓展: 标签名可以自定义。
  • 标记语言: 这门语言完全由标签构成的。

1.2 XML的作用

  1. 描述数据之间的关系。
  2. 用于不同系统之间的数据传输

1.3 XML 与HTML 的主要差异

区别 HTML XML
功能 制作网页,主要用于表示层 用于配置文件,传递数据
大小写 不区分大小写<br><BR> 区分大小写,<abc><ABC>是不同的
语法严谨 不严谨,如果一个标签有开头,没有结尾。
浏览器也可以解析。
严谨,标签开头和结尾必须严格配对
可扩展性 没有可扩展性,所有的标签都是固定好,
每个标签的功能固定。
所有的标签都是人为创造的,可以扩展。

2. XML文件组成

2.1 XML文件的组成元素

  1. 文档声明
  2. 标签元素Element
  3. 属性Attribute
  4. 注释Comment
  5. 转义字符(实体字符)
  6. 字符数据区(用于显示大量的特殊字符的时候)
  7. 处理指令(不常用)

2.2 文档声明

声明:<?xml version="1.0" encoding="UTF-8" ?>
格式: 以<?xml开头,以?>结尾
位置:必须出现在XML 文件的第1 行

2.2.1 文档声明的三个属性

  • version: 用于指定XML 使用哪个版本,固定的写法1.0
  • enconding :指定当前XML 编码
  • standalone: yes/no 默认是yes,这个XML 文件是否是一个单独的文档

2.3 标签元素Element

  • 语法:<开头,>结尾, 中间是标签名;
  • 主体部分:分为有主体和无主体标签,主体部分可以包含文本或其它的子元素;
  • 空元素:无主体标签也必须要关闭;
  • 命名:不能有空格,不能有冒号,数字不能开头
  • 根元素:每个XML 文档必须有且只有一个根元素

2.4 属性Attribute

  • 属性位置:必须放在开始标签中;
  • 属性的值:必须使用单引号或双引号引起来
  • 在同一个标签中不能同时出现多个同名的属性
  • 命名中不能出现空格和冒号

2.5 注释Comment

<!--注释内容-->

  • 注意:不可嵌套

2.6 转义字符(实体字符)

特殊字符需要转义才能显示,常用的有

特殊字符 转义字符
< &lt;
> &gt;
&quot;
&apos;
& &amp;
空格 &nbsp;

2.7 字符数据区

  • 字符区的内容xml 文件的解释器在解释的时候,全部的内容都会当成普通的文本处理,即使遇到了特殊的符号也会只当成普通的文本去处理。

  • 格式:<![CDATA[ 文本数据 ]]>

  • 定义:不由XML 解析器进行解析的纯文本数据
  • 不可嵌套

2.8 处理指令

  • 处理指令,简称PI(Processing instruction)用来指挥解析引擎如何解析XML 文档内容。

  • 格式:<?xml-stylesheet 开头,?>结尾

    eg:`<?xml-stylesheet type="text/css" href="文件名.css"?>

3. XML文件的约束

  • 作用:用于限制xml文件出现的元素范围
  • xml约束文件分类:

    • DTD 约束
    • Schema 约束
  • 一般不需要编写约束,直接引入已编写完

3.1 DTD约束

3.1.1 概念

  • 定义:Document Type Definition 文档类型定义
  • 作用:用来约束XML 文件的,它本身是一个文本文件

3.1.2 导入格式

导入DTD文件方式 描述
<!DOCTYPE 根元素SYSTEM "DTD 文件"> 系统的DTD 文件,使用范围比较小,一般用于公司,不对外开放的DTD 文件
<!DOCTYPE 根元素PUBLIC "DTD 文件"> 公共的DTD 文件,用于互联网上,使用广泛的用途
<!DOCTYPE 根元素[dtd 文件的元素]> xml 文件与dtd 文件混合在一起。

3.1.3 DTD文件写法(理解)

基本写法如下

<!ELEMENT 书架 (书+)>  <!--根元素,包含1个或多个子元素-->
        <!ELEMENT 书 (书名,作者,售价)>  <!--子元素内包含三个子元素-->
        <!ELEMENT 书名 (#PCDATA)> <!--PCDATA指文本-->
        <!ELEMENT 作者 (#PCDATA)>
        <!ELEMENT 售价 (#PCDATA)>
导入方法1
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 SYSTEM "bookshelf.dtd"><!--写法1,使用<!DOCTYPE 根元素SYSTEM "DTD 文件">-->
<书架>
    <>
        <书名>哈利波特</书名>
        <作者>JK罗琳</作者>
        <售价>49.9</售价>
    </>
</书架>
导入方法2
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 [<!ELEMENT 书架 (书+)>
        <!ELEMENT 书 (书名,作者,售价)>
        <!ELEMENT 书名 (#PCDATA)>
        <!ELEMENT 作者 (#PCDATA)>
        <!ELEMENT 售价 (#PCDATA)>]><!--写法2,使用<!DOCTYPE 根元素 [dtd文件内容]>-->
<书架>
    <>
        <书名>哈利波特</书名>
        <作者>JK罗琳</作者>
        <售价>49.9</售价>
    </>
</书架>

3.6 Schema约束

  • xml不能判断较多的数据类型,功能比较简单

  • 而Schema功能更加强大,数据类型约束更完善,可取代DTD

3.6.1 Schema约束的使用

  1. 新建schema 约束文件(固定格式)

    <?xml version="1.0" encoding="UTF-8" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
              targetNamespace="名称空间"
              elementFormDefault="qualified">
       <xs:element name='根元素' >
           <xs:complexType>
               <xs:sequence maxOccurs='unbounded' >
                   <xs:element name='子元素' >
                       <xs:complexType>
                           <xs:sequence>
                               <xs:element name='子元素下的子元素1' type='xs:string' />
                               <xs:element name='子元素下的子元素2' type='xs:string' />
                           </xs:sequence>
                       </xs:complexType>
                   </xs:element>
               </xs:sequence>
           </xs:complexType>
       </xs:element>
    </xs:schema>
  2. 使用schema文件创建xml文件:

    <根元素 xmlns="名称空间" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="名称空间 xsd约束文件名">
    </根元素>
注意事项
  1. 名称空间(targetNamespace): 任何schema 文件都有一个名称空间,schema 名称空间是一个xsd 文件的唯一标记。相当于一个id 号,引入的时候必须要使用名称空间进行引入。
  2. 一般工程不需要自行编写schema文件,只需要根据相关的约束文件编写所需的xml文件即可

3.6.2 示例代码

xsd文件:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.baidu.com" <!--名称空间-->
           elementFormDefault="qualified">
    <xs:element name='书架' >
        <xs:complexType>
            <xs:sequence maxOccurs='unbounded' >
                <xs:element name='书' >
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name='书名' type='xs:string' />
                            <xs:element name='作者' type='xs:string' />
                            <xs:element name='售价' type='xs:double' />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<书架 xmlns="http://www.baidu.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.baidu.com books.xsd">
<>
    <书名>哈利波特</书名>
    <作者>JK罗琳</作者>
    <售价>49.9</售价>
</>
</书架>

4. XML解析技术概述(重要)

4.1 XML解析的概述

  • 对xml文件解析,读取其中的数据

4.2 解析方式和解析器

4.2.1 三种解析方式

4.2.1.1 DOM
  • DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象
  • 优点:元素与元素之间保留了结构关系,可以进行增删改查操作。
  • 缺点:因为整个XML文档被加载到内存中,如果XML过大,可能出现内存溢出
4.2.1.2 SAX
  • SAX:一种速度更快,更有效的方法。逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都触发对应的事件
  • 优点:处理速度快,可以处理大文件。
  • 缺点:只能读,逐行后将释放资源,解析操作繁琐。
4.2.1.3 PULL
  • Android内置的XML解析方式,原理与SAX相同

4.3 DOM常见的解析开发包

  • JAXP:Oracle公司提供支持DOM和SAX开发包

  • Dom4j:比较简单的的解析开发包,将整个XML加载到内存中做为一棵DOM树。

  • JDom:与Dom4j类似

  • Jsoup:功能强大DOM方式的XML解析开发包,同时对HTML解析也很方便。

5. Jsoup的基本使用(重要)

  • Jsoup是一款Java 的XML解析器,可直接解析某个URL地址、HTML文本内容和已经存在的文件。
  • Jsoup它提供了一套非常省力的API,可通过DOM,CSS以及类似于CSS选择器的操作方法来取出和操作数据。

5.1 DOM解析原理

  • 与HTML的DOM编程相同。XML的DOM会将整个XML文档加载到内存,生成一个DOM树,并获得一个Document对象,通过Document对象就可以对DOM进行操作。
  • 与HTML相同,每个元素、属性和文本都是节点,类型为Node。而元素具有独有的类型:Element。注意,Element是Node的子类

5.2 获取Document文档对象三种方式

由于所有节点都封装到Document对象中,只要获得Document对象,就可以获取xml的所有节点

5.2.1 利用html代码获得(不常用)

- static Document parse(String html);
    ->将该html内容转换为一个document对象。
    ->参数String html是整个html文件的内容

☞如果html内容太多,使用该方式将非常不方便,一般很少使用

5.2.2 利用file文件获得

- static Document parse(File file,"码表");
    根据本地的资源文件生成document对象
5.2.2.1 步骤及注意事项
  1. 资源文件要求必须置于本模块的src目录下;
  2. 通过Class对象获得类路径,Class对象可以任意;
  3. 使用Class对象的getResource()方法获得类路径,类路径必须以/开头(可理解为当前src目录);
  4. 使用getPath()方法获得类路径对应字符串,并据此创建File对象;
  5. 根据File对象获得Document对象
5.2.2.2相关方法
- URL getResource("/xml文件名");
    根据文件名路径获得文件资源URL对象;
- String getPath();
    获得URL对象的真实路径
5.2.2.3示例代码
public class Demo02 {
    public static void main(String[] args) throws IOException {
        //获得类路径
        String path = Demo02.class.getResource("/person.xml").getPath();
        //创建File对象
        File file = new File(path);
        //生成document对象。
        Document document = Jsoup.parse(file, "UTF-8");
        System.out.println(document);
    }
}

5.2.3 利用url获取Document对象

- static org.jsoup.Connection connect(String url);
    通过URL字符串创建连接对象
- Document get();   通过连接对象返回一个Document对象
5.2.3.1 步骤
  1. 定义一个具体html网页的url;
  2. 调用connect()方法,创建一个连接对象;
  3. 调用连接对象的get()方法,获得Document对象
5.2.3.2 示例代码
public class Demo03 {
    public static void main(String[] args) throws IOException {
        //根据指定url获得Connection对象
        Connection connection = Jsoup.connect("http://baidu.com");
        //根据连接对象获得Document对象
        Document document = connection.get();
        System.out.println(document);
    }
}

5.3 根据标签属性获得节点

返回类型 Document对象的方法 说明
Element getElementById(String id) 通过id得到唯一元素对象
Element*s* getElementsByTag(String tagName) 通过标签名得到一组元素
Element*s* getElementsByClass(String className) 通过类名得到一组元素对象

5.3.1 示例代码

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //获得Document对象
        Document document = Jsoup.parse(new File(Demo01.class.getResource("/index.html").getPath()),"utf-8" );
        //1.获取index.html中元素属性id="header"的一个元素并打印输出
        Element element = document.getElementById("header");
        System.out.println(element);
        System.out.println("---------");
        //2.获取index.html中所有h2标签名称的元素列表并打印输出
        Elements elements = document.getElementsByTag("h2");
        elements.forEach(System.out::print);
        System.out.println("---------");
        //3.获取index.html中所有元素含有class属性值为fl并打印输出
        elements = document.getElementsByClass("fl");
        elements.forEach(System.out::print);
    }
}

5.4 根据css选择器获得节点(元素)

5.4.1 css选择器相关方法

返回类型 方法 说明
Elements select(String cssQuery) 作用:通过选择器得到多个元素
Element selectFirst(String cssQuery) 作用:通过选择器得到第一个元素

其中,String cssQuery指css选择器:

选择器类型 选择器语法
ID选择器 #id
class选择器 .类名
标签选择器 标签名
属性选择器(属性名) [属性名]
属性选择器(属性值) [属性名=属性值]

5.4.2 示例代码

public class Demo02 {
    public static void main(String[] args) throws IOException {

    //获得Document对象
        Document document = Jsoup.parse(new File(Demo02.class.getResource("/index.html").getPath()), "utf-8");

        //1.获取id="footer"元素并输出元素名称
        Elements elements = document.select("#footer");
        print(elements);
        System.out.println("---------");
        //2.获取index.html中所有元素含有class属性值为item并打印输出元素体内容
        elements = document.select(".item");
        print(elements);
        System.out.println("---------");

        //3.获取index.html中所有h3标签名称的元素列表并打印输出元素名称
        elements = document.select(".item");
        print(elements);
        System.out.println("---------");

        //4.获取index.html中含有属性data-toggle所有元素并打印输出元素名称和元素体数据
        elements = document.select("[data-toggle]");
        print(elements);
        System.out.println("---------");

        //5.获取index.html中属性role值为"tablist"的所有元素列表并打印输出元素名称
        elements = document.select("[role=tablist]");
        print(elements);

    }
    private static void print(Elements elements) {
        elements.forEach(System.out::print);
    }
}

5.5 组合选择器

选择器代码 说明
标签名.类名 交集选择器,同时指定标签名和类名的选择器
标签名[属性名] 得到某标签,包含指定属性的标签。
父元素 子元素 层级选择器,找某个元素下的所有子元素,选择器之间使用空格隔开
兄弟A+兄弟B 查找在A元素后面第一个同级元素B

5.5.1 示例代码

public class Demo03 {
    public static void main(String[] args) throws IOException {
        //获得Document对象
        Document document = Jsoup.parse(new File(Demo03.class.getResource("/index.html").getPath()), "utf-8");

        //1.获取index.html中div元素类名为item的元素,并打印元素数据
        Elements elements = document.select("div.item");
        elements.forEach(System.out::print);
        System.out.println();
        System.out.println("==============================");

        //2.获取index.html中a元素含有属性data-toggle的所有元素列表并打印元素数据
        elements = document.select("a[data-toggle]");
        elements.forEach(System.out::print);
        System.out.println();
        System.out.println("==============================");

        //3.获取index.html中属性id值为"banner"的所有div子元素并打印元素数据
        elements = document.select("#banner div");
        elements.forEach(System.out::print);
        System.out.println();
        System.out.println("==============================");

        //4.获取index.html中class="navitem"元素后面同级第一个兄弟section元素并打印元素数据
        elements = document.select(".navitem+section");
        elements.forEach(System.out::print);
    }
}

5.6 补充Element元素相关方法

Element对象的方法 说明
String attr(“属性名”) 得到元素指定属性的值
Elements children() 得到当前元素所有的子元素,返回集合
String tagName() 得到元素的标签名字
String text() 得到元素主体内容中的文本

5.6.1 示例代码

需求:已有xml保存书的信息,已有一个对应的类Book(String category, String title, String author, int year, double price),使用DOM解析xml,封装成List,并且输出封装好的集合

准备xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<bookstore>
    <book category="CHILDREN">
        <title>Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="WEB">
        <title>Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>

Book类代码省略

main代码如下:

public class Demo03 {
    public static void main(String[] args) throws IOException {
        //获得Document对象
        Document document = Jsoup.parse(new File(Demo03.class.getResource("/books.xml").getPath()), "utf-8");
        //使用dom解析
        Elements books = document.select("book");
        //创建List存放book对象
        List<Book> bookList = new ArrayList<>();
        //遍历books获得每个元素
        for (Element element : books) {
            //创建对象
            Book book = new Book();
            //获得属性值
            String category = element.attr("category");
            book.setCategory(category);
            //获得element的所有子元素
            Elements children = element.children();
            //遍历children
            for (Element child : children) {
                //获得每个子元素的tagName和text,然后进行判断赋值
                String tagName = child.tagName();
                String text = child.text();
                if ("title".equalsIgnoreCase(tagName)) {
                    book.setTitle(text);
                } else if ("author".equalsIgnoreCase(tagName)) {
                    book.setAuthor(text);
                } else if ("year".equalsIgnoreCase(tagName)) {
                    book.setYear(Integer.parseInt(text));
                } else if ("price".equalsIgnoreCase(tagName)) {
                    book.setPrice(Double.parseDouble(text));
                }
            }
            //每循环一次就给bookList添加元素
            bookList.add(book);
        }
        //输出bookList
        for (Book book : bookList) {
            System.out.println(book);
        }
    }
}

6. xPath表达式

6.1 概念

  • JsoupXpath 是一款纯Java开发的使用xpath解析HTML的解析器,JsoupXpath不是jsoup的一部分,是在jsoup基础上进行的扩展。
  • XPath 使用路径表达式来选取HTML或XML文档中的元素节点或属性节点。

6.1.1使用步骤

导包—>写xPath表达式

6.1.2四种XPath语法方式:

1)绝对路径
2)相对路径
3)全文搜索
4)条件筛选

6.2 核心API方法

6.2.1 获得核心类JXDocument

方法 说明
public JXDocument(Document doc) 通过构造方法创建JXDocument对象
参数:org.jsoup.nodes.Document对象
List selN(String xpath) 通过xpath表达式得到指定的节点对象JXNode
返回一个节点集合
JXNode selNOne(String xpath) 通过xpath表达式得到符合条件的节点对象,返回一个节点
节点:包含属性Attribute或元素Element

selN()相当于css选择器获得元素的select(),selNOne相当于css选择器获得元素的selectFirst()

6.2.2 节点JXNode的API

方法 说明
Element getElement() 通过节点得到它的元素
List sel(String xpath) 用在相对路径上,从当前节点开始向下查询其它的子节点

6.3 绝对路径

6.3.1 语法

  • 绝对路径必须从根元素开始写路径,所以必须以/开头,/代表了根标签;
  • 绝对路径找节点绝对不能跳级 去寻找(即不能跳过路径下所有父元素);
  • 路径中不能出现标签

6.2.2 示例代码

public class Demo01 {
    public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
        Document document = Jsoup.parse(new File(Demo01.class.getResource("/index.html").getPath()),"utf-8" );
        //使用Document对象获得对应的额JXDocument对象
        JXDocument jxDocument = new JXDocument(document);
        //需求1: 采用绝对路径获取从根节点开始逐层的/body/div/ul/li节点列表并打印信息
        List<JXNode> jxNodes = jxDocument.selN("/body/div/ul/li");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
        //需求2: 找到head里面link标签
        jxNodes = jxDocument.selN("/head/link");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
    }
}

6.4 相对路径

6.4.1 语法

  • 相对路径指的是相对于当前的路径,相对路径找节点就是相对于当前的路径找到需要的节点
  • 所以需要判断执行sel()查找节点的是哪个对象
格式 说明
子元素/孙元素 相对当前路径元素里面的子元素的选取
./子元素/孙元素 功能与上面的写法一样 . 表示当前路径
/子元素/孙元素 相对当前节点元素位置继续查找节点,需要使用JXNode.sel(xpath)的方法执行相对路径表达式。

其实上面三种是等价的,最常用的是第一种

注意事项
  1. 使用相对路径前需要用绝对路径获得当前的对象,此时xpath的/不可省略!!
  2. 当前对象使用相对路径sel()时,xpath才可以省略.以及/

6.4.2 特殊的方法

  • 相对路径对比其余三种方式有特有的方法获取元素:sel()

6.4.3 示例代码

public class Demo02 {
    public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
        //需求:先采用绝对路径获取body节点,再采用相对路径获取下一级div节点列表并打印信息

        //获得JXDocument对象
        JXDocument jxDocument = new JXDocument(Jsoup.parse(new File(
                Demo02.class.getResource("/index.html").getPath()), "utf-8"));

        //使用绝对路径获得当前的元素(body)
        JXNode body = jxDocument.selNOne("/body");  //中间的“/”不可省略
        //根据相对路径获得下一级的div节点
        List<JXNode> jxNodes = body.sel("div");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
    }
}

6.5 全局搜索

6.5.1 全文搜索获得不同节点语法

获取类型 语法代码
获取元素节点 元素名
获取属性节点 @属性名

6.5.2 全文搜索语法

格式 说明
//子元素//元素或@属性(基本格式) “//”符号,不用逐级写路径,可以直接选取到对应的节点,全文搜索匹配不需要按照逐层级写。

例子:

示例 含义
//li 全文搜索所有的li元素列表,不论li在哪一级元素
//div/a/img 全文搜索所有的div,再逐层级搜索下面的a标签下的img元素
//link/@href 全文搜索link元素,得到它的href属性,属性名前加@符号(注意在@前不要漏了/

6.5.3 示例代码

public class Demo03 {
    public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
        Document document = Jsoup.parse(new File(Demo03.class.getResource("/index.html").getPath()),"utf-8" );
        //使用Document对象获得对应的额JXDocument对象
        JXDocument jxDocument = new JXDocument(document);

        //需求1: 直接全文搜索所有的 li 元素列表并打印
        List<JXNode> jxNodes = jxDocument.selN("//li");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
        //需求2: 直接全文搜索所有的 div,再逐层级搜索下面的 a 元素下的 img 元素列表并打印
        jxNodes = jxDocument.selN("//div/a/img");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
        //需求3: 接获取 link 元素里面 href 属性的值,注意属性要用@符号
        jxNodes = jxDocument.selN("//link/@href");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
    }
}

6.6 条件筛选

  • 根据条件过滤选取节点

6.6.1 语法

格式 说明
//元素[@属性=value] 获取元素属性=value的元素
//元素[@属性>value]/@属性 获取元素属性>value的元素的所有属性的值
//元素[@属性=value]/text() 获取符合条件元素的纯文本数据
//元素[@属性=value]/html() 获取符合条件元素的html数据(包括标签)
注意事项
  1. 如果value是一个包含“-”的字符串,那么需要用单引号括住

6.6.2 示例代码

public class Demo04 {
    public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
        Document document = Jsoup.parse(new File(Demo04.class.getResource("/index.html").getPath()),"utf-8" );
        //使用Document对象获得对应的额JXDocument对象
        JXDocument jxDocument = new JXDocument(document);

        //需求1: 搜索li,属性为class="nav-active"的元素并打印
        List<JXNode> jxNodes = jxDocument.selN("//li[@class='nav-active']");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
        //需求2: 属性为data-slide-to大于0的元素,再查询data-slide-to的属性值
        jxNodes = jxDocument.selN("//li[@data-slide-to>0]/@data-slide-to");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
        //需求3: 搜索a标签,属性为href="login.html"的元素,得到它的文本。
        jxNodes = jxDocument.selN("//a[@href='login.html']/text()");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/KeepStruggling/article/details/82455222