一.XML基础
1.XML 基础概念
-
定义:XML 即可扩展标记语言(Extensible Markup Language),用于标记电子文件,使其具有结构性。它是一种允许用户对自己的标记语言进行定义的源语言,可用来标记数据、定义数据类型。
-
设计宗旨与应用:XML 的设计宗旨是传输数据,而非显示数据。在 web 中应用广泛,是各种应用程序之间数据传输最常用的格式。
-
与 HTML 的区别:
- HTML 用于定义数据的展示,专注于数据呈现的样子;XML 用于传输和存储数据。
- 两者都用标签组织文本内容,但 HTML 有预定义的标签,而 XML 没有预定义标签,需自行定义。
-
特点:
- 设计宗旨为传输数据。
- 标签需自行定义。
- 具有自我描述性。
- 是 W3C 的推荐标准。
-
文档结构:
-
XML 声明(可选) :定义 XML 的版本和所使用的编码,如
<?xml version="1.0" encoding="UTF-8"?>
,它不属于 XML 本身的组成部分,无关闭标签。 -
DTD 文档类型定义(可选) :此部分原文未详细阐述,它主要用于定义 XML 文档的合法构建模块,可约束 XML 文档的结构和元素类型等。
-
文档元素:包括根元素及子元素等。例如以下 XML 文档实例:
<?xml version="1.0" encoding="UTF-8"?> <!--XML 声明--> <fruits> <fruit>这是一个香蕉</fruit> <fruit color="红色">这是一个苹果。</fruit> </fruits>
-
说明:
- 第一行是 XML 声明,定义版本为 1.0,编码为 UTF - 8 。
<!--XML 声明-->
为 XML 注释。- 第二行
<fruits>
是文档的根元素,它是所有其他元素的父元素。 - 后续
<fruit>
等为子元素及元素结尾。 - 整个 XML 呈现树形结构,有根节点(如
<fruits>
)和子节点(如<fruit>
等)。
-
-
-
元素:XML 元素指从开始标签直到结束标签的部分(包括标签)。一个元素可以包含:
- 其他元素(子元素),如
<fruits>
包含<fruit>
。 - 文本,如
<fruit>这是一个香蕉</fruit>
中的 “这是一个香蕉” 。 - 属性,如
<fruit color="红色">这是一个苹果。</fruit>
中的color="红色"
。
- 其他元素(子元素),如
2.XML 语法规则
-
XML 声明位置:XML 声明文件是可选部分,若存在需放在文档第一行。
-
根元素要求:XML 必须包含根元素,它是所有其他元素的父元素,如上述例子中的
<girls>
。 -
标签规则:
- 关闭标签要求:所有 XML 元素都必须有关闭标签,省略关闭标签是非法的,例如
<p>This is a paragraph</p>
。但需注意,XML 声明没有关闭标签,因为它不属于 XML 元素。 - 大小写敏感:XML 标签对大小写敏感,标签
<Letter>
与标签<letter>
不同,打开标签和关闭标签必须使用相同的大小写,如<message>这是正确的。</message>
。 - 正确嵌套:在 XML 中,所有元素都必须彼此正确地嵌套,如
<b><i>This text is bold and italic</i></b>
,<i>
元素在<b>
元素内打开,就在<b>
元素内关闭。 - 属性值引号:与 HTML 类似,XML 可拥有属性(名称 / 值的对),且 XML 的属性值须加引号。例如
<note date="08/08/2008">
是正确的,而<note date=08/08/2008>
是错误的。
- 关闭标签要求:所有 XML 元素都必须有关闭标签,省略关闭标签是非法的,例如
3.XML 数据类型
-
PCDATA:被解析的字符数据,其中的标签会被当作标记来处理,实体会被展开。例如在一般的 XML 文本内容中,大多属于 PCDATA 类型,标签会按 XML 语法规则解析。
-
CDATA:不被解析的字符数据,其中的标签不会被当作标记来对待,实体也不会被展开。常用于需要包含大量特殊字符或不想让 XML 解析器处理的文本,例如在 XML 中嵌入一段 JavaScript 代码时,可使用 CDATA 部分来包裹代码,确保代码中的尖括号等特殊字符不被误解析。如:
<![CDATA[ function example() { console.log('This is a CDATA section'); } ]]>
二.DTD
1.DTD 概述
-
定义:
- DTD(Document Type Definition)即文档类型定义,是用来控制文档格式规范的,由 XML 设计者或作者开发。
- 它定义了 XML 中存在哪些标签、元素拥有哪些属性以及元素的内部结构等。
-
DTD 实例说明:
<!ELEMENT bookstore (book)*> <!-- 定义了根元素 bookstore,它可以包含零个或多个 book 元素 --> <!ELEMENT book (title, author, price)> <!-- 定义了 book 元素,它包含三个子元素:title、author 和 price,且必须按此顺序出现 --> <!ELEMENT title (#PCDATA)> <!-- 定义 title 元素,其内容为可解析的字符数据(PCDATA) --> <!ELEMENT author (#PCDATA)> <!-- 定义 author 元素,其内容为可解析的字符数据(PCDATA) --> <!ELEMENT price (#PCDATA)> <!-- 定义 price 元素,其内容为可解析的字符数据(PCDATA) --> <!ATTLIST book category CDATA "fiction"> <!-- 为 book 元素定义一个名为 category 的属性,其数据类型为字符数据(CDATA),默认值为 "fiction" -->
2.DTD 的声明方式
-
内部声明 DTD:
- 内部声明必须使用
<!DOCTYPE>
元素,将 DTD 嵌入在 XML 文档内部。例如:
<?xml version="1.0" encoding="UTF-8"?> <!--XML 声明--> <!DOCTYPE bookstore [ <!ELEMENT book (title, author, price)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ATTLIST book category CDATA "fiction"> ]> <bookstore> <book category="science"> <title>XML 基础教程</title> <author>张三</author> <price>30.00</price> </book> <book> <title>Java 编程指南</title> <author>李四</author> <price>50.00</price> </book> </bookstore>
- 解释:在这个示例中,
<!DOCTYPE bookstore [... ]>
部分将 DTD 定义包含在方括号内,使其成为 XML 文档的一部分,用于约束bookstore
元素及其子元素的结构和属性。
- 内部声明必须使用
-
外部引用 DTD:
-
介绍:可以从外部的
.dtd
文件中引用,这是一种常用的方式,但也可能是 XXE 漏洞产生的原因。 -
引用格式:
<!DOCTYPE 根元素 SYSTEM "URL">
<?xml version="1.0" encoding="UTF-8"?> <!--XML 声明--> <!DOCTYPE bookstore SYSTEM "bookstore.dtd"> <bookstore> <book category="science"> <title>XML 基础教程</title> <author>张三</author> <price>30.00</price> </book> <book> <title>Java 编程指南</title> <author>李四</author> <price>50.00</price> </book> </bookstore>
-
解释:这里使用
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
声明,将从指定的bookstore.dtd
文件中获取 DTD 信息。常见的 URL 协议有多种,可根据实际情况选择不同的协议进行外部引用-
libxml2 PHP Java .Net file file http file http http https http ftp ftp ftp https php file ftp compress.zlib jar compress.bzip2 netdoc data mailto glob gopher phar
-
-
-
3.DTD 实体
-
实体的概念:
- 实体(ENTITY):如果在 XML 文档中需要频繁使用某一条数据,可以预先给这个数据起一个别名(类似于变量),作为一个 ENTITY,然后在文档中调用它。
- 实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
- 实体可以分为通用实体和参数实体,都可以内部声明或者外部引用。
-
通用实体:
-
介绍:通用实体是在 DTD 中定义的一种实体类型,它允许你为一段文本内容创建一个别名,以便在 XML 文档中多次使用。
-
语法:
<!ENTITY name "value">
。 -
引用:在 XML 中引用通用实体时,由
&
(和号)、实体名称(xxe
)、;
(分号)三部分组成。 -
通用实体在 DTD 中定义,在 XML 文档中都可以使用。例如:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!-- 定义通用实体 --> <!ENTITY companyName "ABC"> <!-- 定义元素 note 包含一个元素 content --> <!ELEMENT note (content)> <!-- 定义元素 content 包含可解析的字符数据 --> <!ELEMENT content (#PCDATA)> ]> <note> <content> This note is &companyName; </content> </note>
-
解释:
-
DTD 部分:
<!DOCTYPE note [... ]>
:使用<!DOCTYPE>
开始内部声明 DTD,其中note
是根元素。<!ENTITY companyName "ABC">
:定义了一个名为companyName
的通用实体,其值为"ABC"
。这个实体可以在后续的 XML 元素中使用。<!ELEMENT note (content)>
:定义note
元素,它包含一个content
子元素。<!ELEMENT content (#PCDATA)>
:定义content
元素,其内容为可解析的字符数据,即可以包含文本内容。
-
XML 部分:
<note>
是根元素,包含一个<content>
子元素。<content>
元素中的&companyName;
是对之前定义的通用实体的引用。当 XML 解析器解析这个文档时,会将&companyName;
替换为"ABC"
,最终解析的内容如下:
-
-
-
参数实体:
-
介绍:参数实体是一种只能在 DTD 中使用的实体,它的主要目的是在 DTD 中创建可重用的部分,使 DTD 的结构更加简洁和易于维护。
-
语法:
<!ENTITY % name "value">
-
引用:在 XML 中引用参数实体时,由
%
(百分号)、实体名称(xxe
)、;
(分号)三部分组成。 -
示例代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE message [ <!-- 定义参数实体 --> <!ENTITY % commonElements "sender, receiver, body"> <!-- 定义元素 message 包含参数实体所代表的元素序列 --> <!ELEMENT message (%commonElements;)> <!-- 定义元素 sender 包含可解析的字符数据 --> <!ELEMENT sender (#PCDATA)> <!-- 定义元素 receiver 包含可解析的字符数据 --> <!ELEMENT receiver (#PCDATA)> <!-- 定义元素 body 包含可解析的字符数据 --> <!ELEMENT body (#PCDATA)> ]> <message> <sender>Alice</sender> <receiver>Bob</receiver> <body>Hello, Bob! How are you today?</body> </message>
-
解释:
-
DTD 部分:
<!DOCTYPE message [... ]>
:使用<!DOCTYPE>
开始内部声明 DTD,其中message
是根元素。<!ENTITY % commonElements "sender, receiver, body">
:定义了一个参数实体%commonElements;
,它代表"sender, receiver, body"
。<!ELEMENT message (%commonElements;)>
:在定义message
元素时,使用了参数实体%commonElements;
来表示message
元素包含sender
、receiver
和body
元素。<!ELEMENT sender (#PCDATA)>
到<!ELEMENT body (#PCDATA)>
:分别定义了sender
、receiver
和body
元素包含可解析的字符数据,即可以包含文本内容。
-
XML 部分:
<message>
是根元素,它包含了sender
、receiver
和body
元素,这些元素的结构是根据 DTD 中使用参数实体所定义的。
-
-
-
-
预定义实体:
- 第一种引用方法:
第二种引用方法:
-
实体 特殊符号 描述 <
< 小于 >
> 大于 &
& 和号 '
’ 单引号 "
" 双引号