一、XML介绍
XML和HTML很相似,HTML是前端页面标签语言
XML指的是扩展标记语言【Extensible Markup Language】
XML用来传输数据的,不是用来显示数据的,之后学习的HTML是显示数据的
XML标签没有被预定义。<标签>内部是要我们来自定义的<Person></Person>
XML是W3C的标准推荐,3C 的工作是对 web 进行标准化,web就是指的前端
W3C在1988年2月发布的1.0版本,2004年2月又发布了1.1版本,但是1.1版本不像下兼容1.0版本,所以没人用1.1版本,
同时2004年2月W3C又发布了1.0版本的第三版,我们学习使用的就是1.0版本
二、XML和HTML的区别
1.HTML标签语言语法松散,XML语法严格,区分大小写
2.HTML主要是做页面传输,XML主要是做数据传输的
3.HTML所有标签都是定义好的,XML所有标签都是自定义的
三、XML的作用:
1.XML可以作为配置文件,JavaEE框架,SSM框架 大部分都是使用的XML作为配置文件的
2.XML可以存储数据,作为数据交换的载体【使用XML格式进行数据的传输】
四、XML的组成元素
一个标准的XML文件一般是由以下及部分组成:
文档声明、元素、属性、注释、转义字符、字符区
文档声明:<?xml version="1.0" encoding="UTF-8"?>
1.文档声明不用我们去写
2.文档声明必须为【<?xm】开头,以【?结束>】
3.文档声明必须从文档的0行0列位置开始
4.文档声明中常见的两个属性
version:指定的XML文档版本。必须属性,这里一般是选择1.0;
encoding:指定当前文档的编码,可选属性,默认是UTF-8;
元素:(标签),<标签>
1.元素是XML中最重要的组成部分,元素也叫做标签
2.标签分为开始标签和结束标签,开始标签<begin>的话,那么结束标签必须是配套的</begin>来结束
3.开始标签和结束标签中间写的是标签内容,标签内容可以是文本,也可以是其他子标签【子标签】
4.如果标签没有任何内容,那么可以定义为空标签<begin/>
5.标签可以嵌套,但是不能乱嵌套,保证父与子的盒子的逻辑关系
6.一个XML文件只有一个根标签
7.标签名必须符合标识符的命名规则
命名规则:
不能使用XML、xMl、XmL....类似的单词
不能使用空格、冒号等特殊符号
区分大小写
数字不能开头
注释:<!-- 注释的内容 -->
XML注释,以【<!--】开头,以【-->】结尾
注释不能嵌套
idea 上的快捷键是CTRL + /
属性:
1.位置:属性是元素的一部分,它必须出现在元素的开始标签中,不能出现在结束标签中
2.格式:属性的定义格式【属性名="属性值"】,其中属性值必须使用单引号或双引号括起来
3.一个元素可以有0-n个属性,但一个元素中不能出现同名的属性
4.属性名必须要符合标识符的命名规则
转义字符:
因为有些特殊的字符在XML中不会被识别,所以在元素标签里或者属性值中需要使用这些符号就使用转义字符即可
< <
> >
& &
" "
注意:在XML中【<】、【&】是非法的
字符区:
CDATA内部的所有东西都会被解析器忽略,当作文本
<![CDATA[
文本数据
]]>
使用快捷键:CD
五、XML中的约束
(一)DTD约束
根据DTD约束正确的书写XML
在XML技术中可以编写一个文档来约束一个XML文档的书写规范,这就称之为XML约束
约束文档定义在XML文件种允许出现的元素/标签名称、属性以及元素出现的顺序等等
有两种约束:【DTD约束,文件后缀.dtd】、【Schema约束,文件后缀.xsd】
【注意】约束文档不需要我们去写,我们只要按照约束文档的要求去写XML就可以了
先看代码:(XML文件的约束)
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
<!ATTLIST 书
id ID #REQUIRED
编号 CDATA #IMPLIED
出版社 (清华|北大|冬澜教育) "冬澜教育"
type CDATA #FIXED "IT"
>
<!--
对书标签中的属性进行约束分析:
书标签有一个【id】属性,类型为ID类型所以属性值是唯一的,不能以数字开头,
书标签中有一个【编号】属性,类型为CDATA可行,也就是属性值是字符串,约束课有可无
书标签中有一个【出版社】属性,类型为枚举类型,也就是说该属性只能在枚举中选择一个,默认是 冬澜教育
书标签中有一个【type】属性,类型为CDATA,也就是字符串,属性约束是固定值,所以该属性只能是"IT"
-->
代码解析:(分类)
对标签层级关系的约束
<!Element 标签名(子标签,子标签,...)>
数量词:
* 表示元素可以出现0个到多个
+ 表示元素可以出现至少一个
? 表示元素可以是0个或是一个
, 表示元素需要按照顺序显示
| 表示元素需要选择其中的一个
对标签的约束
<!ELEMENT 标签名 标签类型>
标签类型:
EMPTY【空元素,例如<person/>】
ANY【任意类型】
(#PCDATA)【字符串数据】
对属性的约束
<!ATTLIST 标签名
属性名 属性类型 属性约束
属性名 属性类型 属性约束
属性名 属性类型 属性约束
... ...
>
属性类型:
CDATA 表示文本字符串
ID 表示属性值唯一,不能以数字开头
ENUMRATED(DTD没有这个关键字) 表示枚举,只能从枚举列表中任选一项(清华|北大|冬澜教育)
属性约束:
REQUIRED 表示该属性必须出现
IMPLIED 表示该属性可有可无
FIXED 表示该属性的取值为一个固定值
XML文件引入dtd的三种方式
第一种方式:外部本地DTD:DT约束文档在本地,DTD约束文档和XML文档配置文件在同一个目录下
<!DOCTYPE 根元素 书架 SYSTEM "bookdtd.dtd">
第二中方式:外部本地DTD,DTD约束文档在网络上
<!DOCTYPE 书架 PUBLIC"DTD名称" "DTD文档的url">
第三中方式:内部DTD,在XML内部嵌入的DTD,只对当前XML有效
<!DOCTYPE 根元素 [元素声明]
【复制内容如下到XML文件中】:将上面的DTD约束引入到XML文件中
<!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 SYSTEM "bookdtd.dtd">
<书架>
<书 id="1" 编号="10" 出版社="冬澜教育" type="IT">
<书名>从零基础学习Java</书名>
<作者>大块头</作者>
<售价>19.9</售价>
</书>
<书 id="2" 出版社="冬澜教育" type="IT" 编号="11">
<书名>MySQL数据库</书名>
<作者>小不点</作者>
<售价>20.9</售价>
</书>
</书架>
(二)schema约束
Schema和DTD是一样的,也是一种XML文件的约束
Schema约束的后缀格式是 .xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.donglan.com"
elementFormDefault="qualified">
<!-- element:表示元素,也就是对元素进行约束-->
<!-- 跟标签的名称:书架 -->
<xs:element name='书架'>
<!-- complexType:复杂标签 -->
<!-- 书架是一个复杂标签-->
<xs:complexType>
<!-- squence:表示序列的意思,在这里要按照顺序出现 -->
<!-- maxOccurs:最多出现几次,minOccurs:最少出现几次-->
<xs:sequence maxOccurs='2' minOccurs="1">
<!-- 书架的子标签的名称是书-->
<xs:element name='书'>
<!--书 标签 又是一个复杂标签-->
<xs:complexType>
<!-- 书标签的子标签必须按照顺序出现-->
<xs:sequence>
<!-- 书标签的子标签名是 书名,类型为String-->
<!-- 书标签的子标签名是 作者,类型为String-->
<!-- 书标签的子标签名是 售价,类型为String-->
<xs:element name='书名' type='xs:string'/>
<xs:element name='作者' type='xs:string'/>
<xs:element name='售价' type='xs:double'/>
</xs:sequence>
<!-- attribute 表示的是:属性,也就是对属性的约束,optional:表示客源,required:就是必选-->
<xs:attribute name="bid" type="xs:int" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<书架 xmlns="http://www.donglan.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.donglan.com bookSchema.xsd" >
<书>
<书名>斗破苍穹</书名>
<作者>土豆</作者>
<售价>19.9</售价>
</书>
<书>
<书名>斗罗大陆</书名>
<作者>唐家三少</作者>
<售价>20.9</售价>
</书>
</书架>
六、XML解析:Dom4j
解析方式和解析包
解析方式:
常见的三种解析方式:
1.DOM:要求解析器把整个XML文件装载到内存,并解析成一个Document对象
优点:元素与元素之间保留结构关系,我们可以很方便的对其进行增删改查
缺点:XML文档过大的话,可能出现内存溢出
2.SAX:是一种速度更快,更有效的方式,它是逐行扫描,一边扫描一遍解析,并且以时间驱动的方式进行具体的解析,每执行一行,都会触发对应的事件
优点:不会出现内存问题,可以处理大的文件
缺点:只能读,不能回写
3.PULL:Android内置的XML解析方式,类似于SAX
解析器:
就是根据不同的解析方式提供具体实现,有的解析器过去繁琐,为了方便开发人人员,会有提供易于操作的解析开发包
Dom4j:比较简单的解析开发包(日常开发包中用的次数最多的)
DOM解析原理以及结构模型
解析原理:XML DOM 将整个XML文档加载到内存,生成一个DOM树,并且获得一个Document对象
通过Document对象就可以对DOM进行操作
七、Dom4j的基本使用:
使用步骤:
1.导包
2.把jar导入到模块项目中,比那个添加classpath路径依赖
3.创建解析器对象
4.使用解析器读取xml文档,生成Document对象
5.根据根元素获取下面的子元素/属性...
常用方法:
创建解析器对象:SAXReader saxReader = new SAXReader();
解析器读取文件的方法:Document document = saxReader.read("day16\\src\\Books.xml");
Document的方法:
Element rootElement = document.getRootElement();
Element的方法:
- List elements():获取当前元素的值
- String getName():Node的方法【父类方法】,获取元素的元素名称
- String attributeValue(String var1):获取当前元素下某个属性的值
- String getText():获取当前元素的文本值
- Element element(String var1):根据元素名称获取指定元素【有多个的话就获取第一个】
- String elementText(String var1):获取指定子元素的文本值,参数是子元素名称
先创建一个XML文件
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<book id="001">
<name>斗破苍穹</name>
<author>土豆</author>
<sale>99.9</sale>
</book>
<book id="002">
<name>斗罗大陆</name>
<author>唐家三少</author>
<sale>85.50</sale>
</book>
</books>
通过Dom4j解析
// 1.创建解析器对象
SAXReader saxReader = new SAXReader();
// 2.使用解析器读取XML文档,生成Document对象
Document document = saxReader.read(new File("day16\\src\\Books.xml"));
// 3.根据Document对象解析
Element rootElement = document.getRootElement();
System.out.println("根标签/元素" + rootElement);
System.out.println("根标签/元素的名称的名称" + rootElement.getName());
// 4.获取根元素下的所有子元素
List<Element> elements = rootElement.elements();
// 5.遍历循环根元素下的所有子元素
for (Element element : elements) {
System.out.println("根元素的子元素名称:" + element.getName());
System.out.println("根元素下的子元素的id属性值:" + element.attributeValue("id"));
// 6.获取element元素下的所有子元素
List<Element> elements1 = element.elements();
// 7.遍历循环book元素下的子元素
for (Element element1 : elements1) {
System.out.println("book元素下的子元素名:" + element1.getName());
System.out.println("book元素下的子元素的文本值" + elements1);
}
System.out.println("==============================================================");
}// for
// 8.获取根元素下的book子元素(获取第一个)
Element book = rootElement.element("book");
System.out.println("第一个子标签book:" + book.getName());
System.out.println("第一个子标签book的id属性值:" + book.attributeValue("id"));
// 9.获取book元素下的author元素文本值
String author = book.elementText("author");
System.out.println("第一个子节点的作者文本值:" + author);
}
运行结果
八、Dom4j结合XPath解析XML
Dom4j综合XPath解析XML:
概述:XPath其实就是要给路径表达式
Xpath表达式的使用步骤:
1.导入包
2.通过dom4j的SAXReader解析器对象,获取Document对象
3.利用XPath提供的api,结合XPath的语法完成选取XML文档元素节点进行解析操作
document和Elements常用的API:
它们的共同父节点Node中的方法
-List selectNodes(String var1); 获得多个节点【node表达的就是标签、元素】
-Node selectSingleNode(String var1); 获得一个节点【node表达的就是标签、元素】
XPath语法的路径:
1.绝对路径表达式:以/开头的路径,从根元素开始,ps:/元素/子元素/子子元素
2.相对路径表达式:
相对当前节点元素位置继续查找节点,不以/开头
../ 表示上一个元素
./ 表示当前元素
3.全文搜索路径表达式:不论中间有多少层,直接获取所有子元素中满足条件的元素
// 子元素
4.谓语表达式:条件筛选
// 元素[@sttr1=value]
老样子:想创建一个XML文件
<?xml version="1.0" encoding="UTF-8"?>
<天气预报>
<北京 provide='京' id='1'>
<温度>
<最高温度 level="A">18</最高温度>
<最低温度>6</最低温度>
</温度>
<湿度>20%</湿度>
</北京>
<深圳>
<温度>
<最高温度 level="C">36</最高温度>
<最低温度>24</最低温度>
</温度>
<湿度>50%</湿度>
</深圳>
<广州>
<温度>
<最高温度 level="C">32</最高温度>
<最低温度>21</最低温度>
</温度>
<湿度>50%</湿度>
<黄浦区>
<温度>
<最高温度 level="C">31</最高温度>
<最低温度>22</最低温度>
</温度>
<湿度>50%</湿度>
</黄浦区>
<天河区>
<温度>
<最高温度 level="C">30</最高温度>
<最低温度>26</最低温度>
</温度>
<湿度>50%</湿度>
</天河区>
</广州>
</天气预报>
Dom4j结合XPath解析XML
public static void main (String[] args) throws DocumentException {
// 1.创建解析器对象
SAXReader saxReader = new SAXReader();
// 2.使用解析器对象读取XML文件,生成Document对象
Document document = saxReader.read(new File("day16_XML\\src\\tianqi.xml"));
// 3.使用document中的节点选择的方法获取某个节点的数据
/*
* 获取深圳的最高温度
* 绝对路径:根节点开始
* 相对路径:相对某个节点开始
* selectSingleNode()该方法返回的是Node对象
* Element是Node的子类,所以我们需要进行向下转型
* 因为需要使用Elements对象获取该节点的文本数据
* */
Element element1 = (Element) document.selectSingleNode("/天气预报/深圳/温度/最高温度");
System.out.println("深圳的最高温度是:" + element1.getText());
// 使用相对路径
// 需求:获取广州黄浦区的最低温度
Element element2 = (Element) element1.selectSingleNode("../../../广州/黄浦区/温度/最低温度");
System.out.println("广州黄浦区的最低温度" + element2.getText());
// 全文搜索路径表达式
// 需求:获取整个XMl中所有的湿度
List<Element> list1 = document.selectNodes("//湿度");
for (Element element3 : list1) {
System.out.println(element3.getName() + "," + element3.getText());
}
// 谓语表达式
// 10.获取整个XML文件中所有最高温度标签的level属性值为C的元素
List<Element> list2 = document.selectNodes("//最高温度[@level='C']");
for (Element element4 : list2) {
System.out.println(element4.getName() + "," + element4.getText() + "," + element4.attributeValue("level"));
}
}