一、XML

1.1 XML概述
概念
XML(Extensible Markup Language):可扩展标记语言
可扩展:标签都是自定义的。
发展历程
HTML和XML都是W3C(万维网联盟)制定的标准,最开始HTML的语法过于松散,于是W3C制定了更严格的XML语法标准,希望能取代HTML。但是程序员和浏览器厂商并不喜欢使用XML,于是现在的XML更多的用于配置文件及传输数据等功能。
是谁造成的HTML语法松散?
浏览器厂商。最开始W3C制定HTML的时候语法还是比较严格的。但浏览器厂商为了抢占市场,语法错误也可以解析成功HTML,最后“内卷”到HTML即使语法非常混乱也是可以被浏览器解析。

tips:归根到底是语法的制定者和使用者不一致造成了HTML语法混乱,JAVA语法严格就是因为java语言的运行工具java虚拟机也是sun公司(现在是oracle)出品的,语法不通过不让运行。
为什么程序员不使用XML写前端页面?
因为程序员松散惯了,不想写很严格的代码。同样挣一万块钱,谁会从每月上一天班的公司跳槽到996的公司呢?
二、XML功能
2.1 配置文件
在今后的开发过程当中我们会频繁使用框架(框架:半成品软件),使用框架时,需要写配置文件配置相关的参数,让框架满足我们的开发需求。而我们写的配置文件中就有一种文件类型是XML。
日后编写大型项目,不可能从头到尾都是原创代码,很多功能前人已经写好,我们只需要使用前人写好的半成品软件(框架),再加入一些符合我们需求的配置即可完成开发。
比如我们组装一台电脑,不可能自己焊接电路板。而是先买入一块主板,这块主板就是半成品软件。根据自己的需求加入一些配置,比如要求流畅运行吃鸡,就需要配置i7处理器、泰坦显卡。

2.2 传输数据
在网络中传输数据时并不能传输java对象,所以我们需要将JAVA对象转成字符串传输,其中一种方式就是将对象转为XML类型的字符串。
比如携程等旅游网站可以买火车票,但他们其实也是替12306卖票,此时他们就需要拿到12306的票务数据。JAVA对象不能在网络上传输,可以转为XML类型的字符串。

2.3 XML和HTML的区别
- XML语法严格,HTML语法松散
- XML标签自定义,HTML标签预定义
三、XML基本语法

- 文件后缀名是.xml
- 第一行必须是文档声明
- 有且仅有一个根标签
- 标签必须正确关闭
- 标签名区分大小写
- 属性值必须用引号(单双都可)引起来
四、XML组成部分

4.1 文档声明
文档声明必须放在第一行,格式为:
属性列表:
- version:版本号(必须,一般是1.0)
- encoding:编码方式(默认utf-8)
4.2 标签
XML中标签名是自定义的,标签名有以下要求:
- 包含数字、字母、其他字符
- 不能以数字和标点符号开头,可以以_开头
- 不能包含空格
4. 3 指令(了解)
指令是结合css使用的,但现在XML一般不结合CSS,语法为:
<?xml-stylesheet type="text/css" href="a.css" ?>
4.4 属性
属性值必须用引号(单双都可)引起来
4.5 文本
如果想原样展示文本,需要设置CDATA区,格式为:
五、约束
5.1 DTD约束

虽然XML标签是自定义的。但是作为配置文件时,也需要遵循一定的规则。就比如在主板上硬盘口只能插硬盘,不能插入其他硬件。约束就是定义XML书写规则的文件,约束我们按照框架的要求编写配置文件。

我们作为框架的使用者,不需要会写约束文件,只要能够在xml中引入约束文档,简单的读懂约束文档即可。XML有两种约束文件类型:DTD和Schema。
DTD是一种较简单的约束技术,引入方式如下:
本地引入:
<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
网络引入:
<!DOCTYPE 根标签名 PUBLIC "dtd文件的位置" "dtd文件路径">
<!ELEMENT students (student*) > //表示根标签是students,有多个student子标签
<!ELEMENT student (name,age,sex)> //表示子标签student的属性有name、age、sex
<!ELEMENT name (#PCDATA)> //表示name的数据类型是纯文本
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED> //表示student中的属性number是唯一的,而且是必须的
<?xml version="1.0" ?>
<!DOCTYPE students SYSTEM "student.dtd" > <!--引入dtd约束文件-->
<students>
<student number="zs">
<name>张三</name>
<age>12</age>
<sex>男</sex>
</student>
<student number="ls">
<name>李四</name>
<age>14</age>
<sex>女</sex>
</student>
</students>
5.2 Schema约束(了解)

Schema比DTD对XML的约束更加详细,引入方式如下:
- 写xml文档的根标签
- 引入xsi前缀:确定Schema文件的版本。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入Schema文件
xsi:schemaLocation="Schema文件定义的命名空间 Schema文件的具体路径"
4.为Schema约束的标签声明前缀
xmlns:前缀="Schema文件定义的命名空间"
<students
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itbaizhan.cn/xml student.xsd"
xmlns="http://www.itbaizhan.cn/xml">

XML解析即读写XML文档中的数据。框架的开发者通过XML解析读取框架使用者配置的参数信息,开发者也可以通过XML解析读取网络传来的数据。XML有如下解析思想:
DOM
将标记语言文档一次性加载进内存,在内存中形成一颗dom树
- 优点:操作方便,可以对文档进行CRUD的所有操作
- 缺点:占内存

SAX
逐行读取,基于事件驱动的。
- 优点:不占内存,一般用于手机APP开发中读取XML
- 缺点:只能读取,不能增删改

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

步骤:
- 导入jar包
- 加载XML文档进内存,获取DOM树对象Document
- 获取对应的标签Element对象
- 获取数据
<?xml version="1.0" ?>
<!DOCTYPE students SYSTEM "student.dtd" > <!--引入dtd约束文件-->
<students>
<student id="zs">
<name>张三</name>
<age>12</age>
<sex>男</sex>
</student>
<student id="ls">
<name>李四</name>
<age>14</age>
<sex>女</sex>
</student>
</students>
package com.it.Jsoup;
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;
//获取xml中所有学生的姓名
public class Jsoup1 {
public static void main(String[] args) throws IOException {
//2.通过类加载器找到xml文件,通过Jsoup加载文件到内存,将文件解析为DON对象Document
ClassLoader classLoader = Jsoup1.class.getClassLoader();
String path = classLoader.getResource("com/it/xsd/student.xml").getPath();
Document document = Jsoup.parse(new File(path), "utf-8");
//3.获取对应的标签Element
Elements names = document.getElementsByTag("name");
//4.获取数据
for (Element name : names) {
String text = name.text();
System.out.println(text);
}
}
}

Jsoup对象:加载xml文档进内存并且转换成Document对象
Document对象:获取标签对象Element
Element对象:获取标签中的数据对象
6.3.1 Jsoup对象详解

常用方法:
- static Document parse(File in, String charsetName):解析本地文件
- static Document parse(String html):解析html或xml字符串
- static Document parse(URL url, int timeoutMillis):解析网页源文件
<?xml version="1.0" ?>
<!DOCTYPE students SYSTEM "student.dtd" > <!--引入dtd约束文件-->
<students>
<student id="zs">
<name>张三</name>
<age>12</age>
<sex>男</sex>
</student>
<student id="ls">
<name>李四</name>
<age>14</age>
<sex>女</sex>
</student>
</students>
package com.it.Jsoup;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/*Jsoup使用*/
public class Jsoup2 {
public static void main(String[] args) throws IOException {
//1、解析本地xml文件
String path = Jsoup2.class.getClassLoader().getResource("com/it/xsd/student.xml").getPath();
Document document = Jsoup.parse(new File(path), "UTF-8");
System.out.println(document);
System.out.println("--------------------------------");
// 解析字符串
Document document1 = Jsoup.parse("<?xml version=\"1.0\" ?>\n" +
"<students\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://www.itbaizhan.cn/xml student.xsd\"\n" +
" xmlns=\"http://www.itbaizhan.cn/xml\">\n" +
"\n" +
" <student number=\"baizhan_0001\">\n" +
" <name>baizhan</name>\n" +
" <age>10</age>\n" +
" <sex>male</sex>\n" +
" </student>\n" +
" <student number=\"baizhan_0002\">\n" +
" <name>sxt</name>\n" +
" <age>11</age>\n" +
" <sex>female</sex>\n" +
" </student>\n" +
"</students>");
System.out.println(document1);
System.out.println("---------------------------------");
// 解析网络资源
Document document2 = Jsoup.parse(new URL("https://www.baidu.com"), 2000);
System.out.println(document2);
}
}