文章目录
XML-DTD的简要总结
声明:
本文部分DTD实例取自W3C教程。
CSDN不支持DTD高亮,使用的XML高亮。
简介
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。
它使用一系列的合法元素来定义文档结构。
包含内容
- 引用方法
- 元素
- 属性
- 实体
- PCDATA
- CDATA
- 参数实体
DTD引用方法
// 内部声明
<!DOCTYPE 根元素 [元素声明]>
// 外部声明(本地和公共计算机)
<!ENTITY 实体名称 SYSTEM "URI/URL"> // 本地计算机
<!ENTITY 实体名称 PUBLIC "publicID" "URI"> // 公共计算机
元素
采用ELEMENT
标签对元素进行声明。元素可以包含文本(PCDATA)、子元素或为空(EMPTY)。
元素声明的格式
类别1:<!ELEMENT 元素名称 类别关键字>
或
类别2:<!ELEMENT 元素名称 (元素内容)> // 元素的内容可以是文本或元素
空元素
空元素属于类别1,EMPTY属于类型关键字。
<!ELEMENT 元素名称 EMPTY>
<!ELEMENT br EMPTY>
// 对应了HTML当中的<br />标签
任意内容的元素
属于类别1,ANY属于类别关键字。
<!ELEMENT 元素名称 ANY>
<!ELEMENT note ANY>
只包含PCDATA元素
属于类别2,完整的PCDATA标签对应位置为元素内容,标签对当中可包含文本。
【内容】
<!ELEMENT 元素名称 (#PCDATA)>
<!ELEMENT from (#PCDATA)>
带有子元素(序列)的元素
带有一个或多个子元素的元素,通过圆括号当中的子元素名称进行声明:
<!ELEMENT 元素名称 (子元素名称 1)>
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
多个子元素由按照逗号分割开的序列进行声明。其子元素必须按照相同的顺序出现在文档当中。
完整声明当中,子元素也必须声明。
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
下面按照子序列的形式进行细分,
声明只出现一次的元素
<!ELEMENT 元素名称 (子元素名称)>
按照此种方法声明后,该元素在文档中必须出现一次且只出现一次。
声明最少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
按照此种方法声明后,该元素在文档中至少出现一次。
声明出现零次或者多次的元素
<!ELEMENT 元素名称 (子元素名称*)>
按照此种方法声明的子元素,可以出现零次或多次。
出现零次或一次的元素
<!ELEMENT 元素名称 (子元素名称?)>
按照此种方法声明的子元素,可以出现零次或一次。
声明"非…/即…"
**(A|B)**即为此结构。
<!ELEMENT note (to,from,header,(message|body))>
分析:此元素必须包含的子元素有to,from,header,以及message|body当中一个。
声明混合型的内容
<!ELEMENT note (#PCDATA|to|from|header|message)*>
可以出现多种类型的元素,且可以出现零次或多次。
属性
简介
属性可以提供有关元素的额外信息。
以名称/值的形式成对出现。
声明属性方法
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
属性类型表
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|…) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认值表
值 | 解释 |
---|---|
值 | 属性的默认值 |
#REQUIRED | 属性值是必需的 |
#IMPLIED | 属性不是必需的 |
#FIXED value | 属性值是固定的 |
默认值
一般的使用方法
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
<square width="100" /> 合法
“square” 被定义为带有 CDATA 类型的 “width” 属性的空元素。如果宽度没有被设定,其默认值为0。
#REQUIRED
<!ATTLIST 元素名称 属性名称 属性类型 #REQUIRED>
<Math num="1234" /> 合法
<Math /> 非法
#IMPLIED
<!ATTLIST 元素名称 属性名称 属性类型 #IMPLIED>
<Math num="1234" /> 合法
<Math /> 合法
#FIXED value
<!ATTLIST 元素名称 属性名称 属性类型 #FIXED "value">
<Company name="Microsoft" /> 合法
<Company name="Google" /> 非法
列举属性值
将属性值设定为固定的合法值之一。
<!ATTLIST 元素名称 属性名称 (en1|en2|..) 默认值>
<!ATTLIST payment type (check|cash) "cash">
<payment type="check" />
<payment type="cash" />
多属性值的声明
<!ATTLIST Student
age CDATA #IMPLIED
name CDATA #IMPLIED
class CDATA #REQUIRED
credit CDATA #REQUIRED>
实体
简介
实体用于定义引用不同文本和特殊字符的快捷方式的变量。
实体是用来定义普通文本的变量,实体引用是实体的引用。
实体可以在内部或外部进行声明。
当文档被 XML 解析器解析时,实体就会被展开。
预定义实体
有一些预留字符涉及到了DTD结构中的关键字符,他的出现会影响实体的正常解析,且容易造成注入攻击,因此需要预定义。
实体引用 | 字符 |
---|---|
< | < |
> | > |
& | & |
" | " |
' | ’ |
要注意的是,
- 转义字符内不包含空格
- 区分大小写
内部实体声明
<!ENTITY 实体名称 "实体的值">
外部实体引用
外部实体可以支持多种协议,如HTTP、FILE等协议。如file://
可以在本地读取有权限读取的任意文件。
<!ENTITY 实体名称 SYSTEM "URI/URL"> // 本地计算机
<!ENTITY 实体名称 PUBLIC "public_ID" "URI"> // 公共计算机
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (😉。
<author>&writer;©right;</author>
参数实体
%file;
(参数实体)是在DTD中被引用的,而&file;
是在xml文档中被引用的。
仅在DTD文档当中使用的解析实体称为参数实体。
常用于针对DTD文档进行使用,方便我们容易的修改或维护DTD文档的结构,降低DTD文档的重复度。
用法
声明关键字和实体,在解析时对文本进行替换以产生作用。
// 一个参数实体的声明格式
<!ENTITY % 参数实体名称 替换文本>
<!ENTITY % peopleParameters "age CDATA #IMPLIED weight CDATA #IMPLIED height CDATA #REQUIRED">
// 使用案例,将想引入的 %参数实体名称; 按此格式进行引用,可在解析式完成文本替换。
<!ATTLIST InsuredPerson %peopleParameters; carrier CDATA #REQUIRED >、
// 其替换结果等效于
<!ATTLIST InsuredPerson
age CDATA #IMPLIED
weight CDATA #IMPLIED
height CDATA #REQUIRED
carrier CDATA #REQUIRED>
重要说明
与一般实体类似,参数实体的置换文本也可位于外部文件中。
此类声明中进行替换的替换形式只能用于DTD外部子集。
在内部子集中,参数实体引用只能位于其他声明当中:此类实体引用的值需要符合语法,否则将影响DTD格式的正规性。
两种重要的文本形式
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据(character data)。
*CDATA 是不会被解析器解析的文本。*在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
我们知道,在使用中,出现XML的预留字符(指&、<、>、"、’)时,需要使用转义字符进行替换。
除了这种方法之外,我们还可以采用CDATA来包含包含这些字符的文字段,以避免解析造成的错误。
其相对于转义字符存在优势
- 可读性强
- 解析速度快
特别的,
]]>
不可包含空格]]>
作为CDATA标签的保留字符串,不可在标签内部出现。
数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。