JavaWeb第十二天

本文详细介绍了XML(可扩展标记语言)的概念、语法、快速入门及组成部分,强调了XML与HTML的区别。XML主要用于存储数据,其严格语法使得数据结构清晰。文章还提及了XML的约束技术,包括DTD和Schema,以及它们的作用。接着,讨论了XML解析的两种主要方式——DOM和SAX,分别阐述了各自的优缺点和适用场景。最后,简要介绍了JSOUP库在解析XML和HTML文档中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、XML

1、概念

Extensible Markup Language可扩展标记语言
可扩展
  标签都是自定义的 只要符合命名规范
功能
  存储文件
  (1)配置文件 properties文件存储简单数据
  (2)在网络中传输
与html的区别
  都是w3c(万维网)开发的
  早期只有html,但浏览器之间的恶性竞争使得html的语法十分松散,怎么写都不会报错
  于是开发了xml,但xml的语法太严格,竞争不过html,转而用来存储数据
  使用标签存储数据结构很清晰,哪个属性属于哪个用户很明确

    <user id='1'>
      <name>zhangsan</name>
      <age>22</age>
    </user>
    <user id='2'>
      <name>lisi</name>
      <age>33</age>
    </user>
    (1)xml标签都是自定义的,html的标签都是预定义的
    (2)xml的语法严格,html的语法松散
    (3)xml是存储数据的,html是展示数据的

语法
  xml文档可以被大部分浏览器解析,只要将其拖进浏览器,没有报错则没有写错
  基本语法
    后缀名.xml
    第一行必须定义为文档声明 不能空着第一行
    xml文档中有且仅有一个根标签
    属性值必须使用引号
    围堵标签必须有结束标签,自闭合标签必须有/
    xml标签名区分大小写
快速入门

            <?xml version='1.0'?>
                    <users>
                        <user id="1">
                            <name>zhangsan</name>
                            <age>22</age>
                            <gender>male</gender>
                            <br/>
                        </user>
                        <user id="2">
                            <name>lisi</name>
                            <age>33</age>
                            <gender>female</gender>
                        </user>
                    </users>

组成部分
  文档声明
    格式:<?xml 属性列表?> ?和<>以及xml之间不能有空格
    属性列表
      version 版本号 1.0是主流版本 必须的属性
      encoding 编码格式 告知解析引擎当前文档使用的字符集 默认ISO-8859-1
          若与文档真实编码格式不一致,则会报错,ANSI是GBK
          idea可以自己识别encoding的值,自动修改文档真实编码
      standalone 是否独立,是否依赖于其它文件 大多数情况下不设置这个属性,
           即使设置了yes也可以依赖于其它文件
           yes 不依赖
           no 依赖
  指令(了解)
    结合css来控制标签样式
    加上<?xml-stylesheet type='text/css' href='a.css'?>之后浏览器就会解析所有标签来展示标签
  内的数据
  标签
    名称自定义
    规则:可以包含字母 数字和其它字符
       不能以数字或标点符号开始
       不能以xml XML Xml等开始
       不能包含空格
    属性
      id属性值唯一
    文本内容
      CDATA区
        该区域中数据会被原样展示
        格式:<![CDATA[数据]]>
约束
  概念
    xml文档作为软件的配置文档,由用户来编写,由软件来解析
    这里的软件指的是半成品软件,即框架,其用户是程序员
    软件为xml文档的编写提供了一个说明文档,规定xml文档的书写规则,
    该说明文档即为约束文档
    我们只需要
      (1)能在xml中引入约束文档
      (2)能简单地读懂约束文档
  分类
    DTD 一种简单的约束技术
    组成:通过ELEMENT定义标签
         ATTLIST定义属性
    引入:
      内部dtd 将约束规则定义在xml文档中
      外部dtd 将约束规则定义在外部的dtd文件中
        本地
        网络
    缺点:
      字符串内容没有约束 如age可以写为aaa
  Schema 一种复杂的约束技术
    引入
users.xml

<?xml version='1.0'?>
<!--<?xml-stylesheet type='text/css' href='a.css'?>-->
<users>
    <user id="1">
        <name>张三</name>
        <age>22</age>
        <gender>male</gender>
        <br/>
    </user>
    <user id="2">
        <name>lisi</name>
        <age>33</age>
        <gender>female</gender>
        <code>
            <![CDATA[
                if(a > b && a > c) {}
            ]]>
        </code>
    </user>
</users>

student.dtd

<!--根标签students中包含0个或多个student标签-->
<!ELEMENT students (student*) >
<!--student标签中包含name age sex3个标签,且个数均为1 要按照顺序定义-->
<!ELEMENT student (name,age,sex)>
<!--#PCDATA指标签内容为字符串-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!--student标签有属性number 为ID类型,值唯一 #REQUIRED指该属性是必须的-->
<!ATTLIST student number ID #REQUIRED>

student.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">

<students>
	<student number="itcast_0001">
		<name>tom</name>
		<age>18</age>
		<sex>male</sex>
	</student>
	
</students>

students.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--外部引入-->
<!--<!DOCTYPE students SYSTEM "student.dtd">-->
<!--内部引入-->
<!DOCTYPE students [
        <!--根标签students中包含0个或多个student标签-->
        <!ELEMENT students (student*) >
        <!--student标签中包含name age sex3个标签,且个数均为1 要按照顺序定义-->
        <!ELEMENT student (name,age,sex)>
        <!--#PCDATA指标签内容为字符串-->
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        <!--student标签有属性number 为ID类型,值唯一 #REQUIRED指该属性是必须的-->
        <!ATTLIST student number ID #REQUIRED>
]>
<!--先输入<才会有代码补全-->
<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>33</age>
        <sex>male</sex>
    </student>
    <student number="s002">
        <name>lisi</name>
        <age>22</age>
        <sex>female</sex>
    </student>
</students>

2、XML解析

操作xml文档,将文档中的数据读取到内存中
操作xml文档
  解析 将文档中的数据读取到内存中
  写入 将内存中的数据写入到xml文档中,持久化地存储
解析XML的方式
  DOM
    将标记语言文档一次性加载进内存中,在内存中形成一棵DOM树
    优点
      操作方便,可以对文档进行CRUD的所有操作
    缺点
      占内存 一般树所占内存是文档的1000到10000倍左右
      不适用于内存小的设备
  SAX
    逐行读取,基于事件驱动
    读一行释放一行,内存中只有一行
    对于标签的读取 是先读取开始标签 再读取文本内容 最后读取结束标签
    为了判断文本内容属于这个标签,需要基于事件驱动,
    读到什么标签就触发一些事件
    优点:
      不占内存,适用于内存小的设备
    缺点:
      只能读取,不能增删改
  在服务器端一般使用DOM 在移动端一般使用SAX
常见解析器
  JAXP SUN公司 支持DOM和SAX思想
  DOM4J 常用于移动端
  JSOUP 一款Java的HTML解析器,可直接解析某个url地址、html文本内容
  PULL Android操作系统内置解析器 SAX方式

二、JSOUP

1、快速入门

(1)导入jar包 将jar包复制到项目中 然后右键Add As Library…
(2)获取Document对象 其代表DOM树
(3)获取对应的标签Element对象
(4)获取数据
students.xml

<?xml version="1.0" encoding="UTF-8" ?>
<students>
    <student number="heima_0001">学生1
        <name id="1">张三</name>
        <age>18</age>
        <sex>male</sex>
    </student>
    <student number="heima_0002">
        <name>李四</name>
        <age>19</age>
        <sex>female</sex>
    </student>
</students>

测试类

public class Demo01Jsoup {
    public static void main(String[] args) throws IOException {
        //2、获取Document对象,根据xml文档获取
        //2.1 获取文件对象之前先获取文件路径
        String path = Demo01Jsoup.class.getClassLoader().getResource("students.xml").getPath();
        //2.2 解析xml文档,加载文档进内存,获取DOM树,即Document对象
        Document doc = Jsoup.parse(new File(path), "utf-8");
        //3、获取标签对象 ctrl+alt+v自动生成变量 Elements继承了ArrayList,泛型是Element
        Elements elements = doc.getElementsByTag("name");
        for (Element element : elements) {
            System.out.println(element);//<name>
                                        //张三
                                        //</name>
                                        //<name>
                                        //李四
                                        //</name>
            //获取标签内容
            System.out.println(element.text());//张三
                                               //李四
        }
    }
}

2、Jsoup对象的使用

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文档 常用于爬虫
Document 文档对象,代表内存中的DOM树
Elements 元素Element对象的集合,可以当作ArrayList来使用
Element 元素对象
Node 节点对象,是上面3个对象的父亲

public class Demo02JsoupObject {
    public static void main(String[] args) throws IOException {
        //Jsoup对象
        //获取Document对象
        //parse(File in, String charsetName);解析xml或html文件的
        String path = Demo02JsoupObject.class.getClassLoader().getResource("students.xml").getPath();
        Document doc1 = Jsoup.parse(new File(path), "utf-8");
        System.out.println(doc1);
        /*
        <!--?xml version="1.0" encoding="UTF-8" ?-->
        <html>
         <head></head>
         <body>
          <student number="heima_0001">
           <name>
            张三
           </name>
           <age>
            18
           </age>
           <sex>
            male
           </sex>
          </student>
          <student number="heima_0002">
           <name>
            李四
           </name>
           <age>
            19
           </age>
           <sex>
            female
           </sex>
          </student>
         </body>
        </html>
         */
        //parse(String html);解析xml或html字符串
        String str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                     "<students>\n" +
                     "    <student number=\"heima_0001\">\n" +
                     "        <name>张三</name>\n" +
                     "        <age>18</age>\n" +
                     "        <sex>male</sex>\n" +
                     "    </student>\n" +
                     "    <student number=\"heima_0002\">\n" +
                     "        <name>李四</name>\n" +
                     "        <age>19</age>\n" +
                     "        <sex>female</sex>\n" +
                     "    </student>\n" +
                     "</students>";
        Document doc2 = Jsoup.parse(str);
        System.out.println(doc2);
        //parse(URL url, int timeoutMillis);通过网络路径获取指定的html或xml文档
        URL url = new URL("https://www.baidu.com");
        Document doc3 = Jsoup.parse(url, 10000);
        System.out.println(doc3);//打印出网页的html文档
    }
}

3、Document对象 继承了Element对象

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

public class Demo03DocumentObject {
    public static void main(String[] args) throws IOException {
        //获取xml文件路径
        String path = Demo03DocumentObject.class.getClassLoader().getResource("students.xml").getPath();
        Document doc = Jsoup.parse(new File(path), "utf-8");
        //获取所有的student对象
        Elements student = doc.getElementsByTag("student");
        //System.out.println(student);
        //获取属性名为id的元素
        Elements idEle = doc.getElementsByAttribute("id");
        //System.out.println(idEle);
        //获取属性number为heima_0001的元素
        Elements numberEle = doc.getElementsByAttributeValue("number", "heima_0001");
        //System.out.println(numberEle);
        //获取属性id为1的元素
        Element elementById = doc.getElementById("1");
        System.out.println(elementById);
    }
}

4、Element元素对象

获取Element对象,这里是获取子元素
  getElementById(String id);根据id属性值获取唯一的Element对象
  getElementsByTag(String tagName);根据标签名获取元素对象集合
  getElementsByAttribute(String key);根据属性名获取元素对象集合
  getElementsByAttributeValue(String key, String value);根据对应的属性名和属性值获取元素对象集合
获取属性值
  String attr(String attributeKey);根据属性名获取属性值 不区分大小写
获取文本内容
  String text();
  String html();获取标签体的所有内容

public class Demo04ElementObject {
    public static void main(String[] args) throws IOException {
        //获取xml文件的路径
        String path = Demo04ElementObject.class.getClassLoader().getResource("students.xml").getPath();
        //获取Document对象
        Document doc = Jsoup.parse(new File(path), "utf-8");
        //通过Document对象获取元素,是获取所有的name标签,有2个
        Elements elementsByTag = doc.getElementsByTag("name");
        System.out.println(elementsByTag.size());//2
        //通过Element获取子元素 获取的是第一个student标签内的name标签,只有1个
        //先获取Element对象
        Elements student = doc.getElementsByTag("student");
        Element stu1 = student.get(0);
        Elements elementsByTag1 = stu1.getElementsByTag("name");
        System.out.println(elementsByTag1.size());//1

        //获取属性值
        String number = stu1.attr("number");
        System.out.println(number);//heima_0001

        //获取文本内容
        String text = stu1.text();//获取标签体的所有文本内容
        System.out.println(text);//学生1 张三 18 male
        String html = stu1.html();//获取标签体的所有内容
        System.out.println(html);//学生1
                                 //<name id="1">
                                 //张三
                                 //</name>
                                 //<age>
                                 //18
                                 //</age>
                                 //<sex>
                                 //male
                                 //</sex>
    }
}

5、快捷查询方式-selector 选择器

Element select(String cssQuery);
  参数参考Selector类中定义的语法

public class Demo05QuickQuery {
    public static void main(String[] args) throws IOException {
        //获取xml文件的路径
        String path = Demo05QuickQuery.class.getClassLoader().getResource("students.xml").getPath();
        Document doc = Jsoup.parse(new File(path), "utf-8");
        //虽然select方法是在Element对象中定义的,但Document对象继承自Element对象,一般使用Document对象调用该方法
        //查询name标签
        Elements name = doc.select("name");
        //System.out.println(name);
        //查询id值为1的元素
        Elements id1 = doc.select("#1");
        //System.out.println(id1);
        //获取属性number为heima_0001的student标签下的age标签
        Elements select = doc.select("student[number='heima_0001'] age");
        System.out.println(select);
    }
}

6、快捷查询方式-XPath

用来确定XML文档中某部分位置的语言
  使用Jsoup的XPath需要独立导入jar包
  查询w3cschool参考手册,使用XPath的语法完成查询

public class Demo06XPath {
    public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
        //获取xml文档的路径
        String path = Demo06XPath.class.getClassLoader().getResource("students.xml").getPath();
        //获取Document对象
        Document doc = Jsoup.parse(new File(path), "utf-8");
        //创建JXDocument对象 其支持XPath的语法
        JXDocument jxdoc = new JXDocument(doc);
        //结合XPath语法查询
        //查询所有student标签 //student获取所有student标签,不考虑位置
        List<JXNode> jxNodes1 = jxdoc.selN("//student");
        for (JXNode jxNode : jxNodes1) {
            //System.out.println(jxNode);
            //将jxNode转换为Element对象,就可以很方便地获取属性值和文本内容了
            Element element = jxNode.getElement();
        }
        //查询所有student标签下的name标签
        List<JXNode> jxNodes2 = jxdoc.selN("//student/name");
        for (JXNode jxNode : jxNodes2) {
            //System.out.println(jxNode);
        }
        //查询student标签下带id属性的name标签
        List<JXNode> jxNodes3 = jxdoc.selN("//student/name[@id]");
        for (JXNode jxNode : jxNodes3) {
            //System.out.println(jxNode);
        }
        //查询student标签下带id属性的name标签,且id=1
        List<JXNode> jxNodes4 = jxdoc.selN("//student/name[@id='1']");
        for (JXNode jxNode : jxNodes4) {
            System.out.println(jxNode);
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值