对大多数Web前端工程师来说,对HTML的doctype即熟悉又陌生。今天我们就八一八doctype相关的知识。
SGML、XML、HTML、XHTML的关系
说doctype之前先得说说这几个*ML之间的关系。
最先有的SGML,它是一个通用的标记语言。然后有了HTML,基于SGML,专门为Web页面而生。
XML是SGML的一个子集,更简单,也更严格。这里是W3C在1997年发的一个对XML和SGML的对比Note。
最后,基于XML重新制定了XHTML。
下图给出了4者之间的关系:
可以看出来,SGML和XML都是通用的标记语言。HTML和XHTML都是通用标记语言在Web领域的特定应用
。既然是特定领域,就需要对可以出现的元素做出精确的定义。所以,就有了文档类型定义—DTD
文档类型定义-DTD
DTD定义了XML文档的结构。定义了合法的标签、属性等。HTML对应的DTD定义了HTML文档中可以出现的标签及其属性。
DTD超简介
想一想,作为DTD需要具备以下能力:定义合法元素、元素内可以包含的元素、元素的闭合;定义元素的属性必选、可选和取值。
声明元素:
<!ELEMENT generic-identifier (content or EMPTY)>
声明属性:
<!ATTLIST element-name {attr-name attr-type default} ...>
default = [#REQUIRED | #IMPLIED | "value" | #FIXED "value"]
含义依次为:必填、可选、可选默认、必选固定
声明实体:
<!ENTITY % entity-name "text">
所有出现%entity-name;
的地方都会被替换为text
(完整DTD教程)
下面是一个简单的DTD实例:
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don"t forget me this weekend!</body>
</note>
看,这里的<!DOCTYPE note...>
是一个自定义的文档类型。
我们的html5的文档类型是<!DOCTYPE html>
,是不是突然明白了什么?
上面的doctype note
是内联的DTD。它定义了当前XML文件可以有一个note标签,其下可包含to,from,heading,body
元素。这几个元素的内容都是PCDATA
类型。
PCDATA(Parsed Character Data)将会被xml解析器parse,CDATA(Character Data)不会被parse。
再来看我们的HTML有哪些DTD:
HTML2.0
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
HTML3.2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
HTML2.0和3.2的doctype中并没有提供下载地址。不过我们也需要不关心了。
HTML4.01后都有提供dtd下载地址(下面省略了Frameset对应的doctype声明):
HTML4.01
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
HTML 4.01 Transitional
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
XHTML 1.0 Strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XHTML 1.0 Transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
XHTML 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
XHTML1.1及之前都是有对应dtd文件的。HTML5没有了。是不是突然感觉生活美好了、世界变清爽了!
HTML5
<!DOCTYPE html>
为什么没有html5.dtd或html5.xsd?
简单来说,html5已经不再是基于SGML或XML了,已经复杂到无法完全用DTD来描述了。
不过经过搜索,我倒是还真找到了一些HTML的dtd:比如,html5.dtd是Komodo Editor 中带的用来校验html5的dtd文件。
HTML5没有对应的DTD,但是XHTML1有啊,我们下载下来看看,里面都有什么!
XHTML1.dtd
将XHTML1.dtd下载下来。(XHTML1.1被分为多个模块,为了方便我们来看XHTML1.dtd)
整体浏览一下,发现前面是一些实体定义:
- Character mnemonic entities
- Imported Names
- Generic Attributes
- Text Elements
- Block level elements
- Content models for exclusions
后面被分为几个部分:
- Document Structure
- Document Head
- Document Body
- Paragraphs
- Headings
- Lists
- Address
- Horizontal Rule
- Preformatted Text
- Block-like Quotes
- Inserted/Deleted Text
- The Anchor Element
- Inline Elements
- Object
- Images
- Client-side image maps
- Forms
- Tables
从文档开头搜索<!ELEMENT
,第一个就是html元素:
<!-- Document Structure -->
<!ELEMENT html (head, body)>
<!ATTLIST html
%i18n;
id ID #IMPLIED
xmlns %URI; #FIXED "http://www.w3.org/1999/xhtml"
>
html元素可以包含head和body元素,有id和xmlns属性。其中id可选,xmlns规定为http://www.w3.org/1999/xhtml
。
接下来看
<!-- Document Head -->
<!ENTITY % head.misc "(script|style|meta|link|object)*">
<!-- content model is %head.misc; combined with a single
title and an optional base element in any order -->
<!ELEMENT head (%head.misc;,
((title, %head.misc;, (base, %head.misc;)?) |
(base, %head.misc;, (title, %head.misc;))))>
<!ATTLIST head
%i18n;
id ID #IMPLIED
profile %URI; #IMPLIED
>
如上面注释所说,head标签必须包含title,可选的base标签,若干可选的script、style、meta、link、object标签。
整个DTD文档中包含很多信息。比如,
通过搜索EMPTY>
你可以找到所有自闭合标签:
<!ELEMENT base EMPTY>
<!ELEMENT meta EMPTY>
<!ELEMENT link EMPTY>
<!ELEMENT hr EMPTY>
<!ELEMENT br EMPTY>
<!ELEMENT param EMPTY>
<!ELEMENT img EMPTY>
<!ELEMENT area EMPTY>
<!ELEMENT input EMPTY>
<!ELEMENT col EMPTY>
通过搜索%Inline;>
可以找到只允许包含内联元素的对象:
<!ELEMENT p %Inline;>
<!ELEMENT h1 %Inline;>
<!ELEMENT h2 %Inline;>
<!ELEMENT h3 %Inline;>
<!ELEMENT h4 %Inline;>
<!ELEMENT h5 %Inline;>
<!ELEMENT h6 %Inline;>
<!ELEMENT dt %Inline;>
<!ELEMENT address %Inline;>
<!ELEMENT span %Inline;>
<!ELEMENT bdo %Inline;>
<!ELEMENT em %Inline;>
<!ELEMENT strong %Inline;>
<!ELEMENT dfn %Inline;>
<!ELEMENT code %Inline;>
<!ELEMENT samp %Inline;>
<!ELEMENT kbd %Inline;>
<!ELEMENT var %Inline;>
<!ELEMENT cite %Inline;>
<!ELEMENT abbr %Inline;>
<!ELEMENT acronym %Inline;>
<!ELEMENT q %Inline;>
<!ELEMENT sub %Inline;>
<!ELEMENT sup %Inline;>
<!ELEMENT tt %Inline;>
<!ELEMENT i %Inline;>
<!ELEMENT b %Inline;>
<!ELEMENT big %Inline;>
<!ELEMENT small %Inline;>
<!ELEMENT label %Inline;>
<!ELEMENT legend %Inline;>
<!ELEMENT caption %Inline;>
通过查看%Inline
(%Block
)对应实体的内容,你可以知道有哪些元素是内联(快级)元素。
Java世界中的dtd(xsd)文件
Java世界中经常可以看到各种XML配置文件。XML之于Java就像JSON之于JavaScript。
这些XML都有对应的DTD文件或XSD。
比如: myBatis Mapper 、Servlet 的web.xml
Jave开发使用的的IDE多可以根据DTD(XSD)给出自动完成提示。不过,通过阅读DTD或XSD,我们还是可以从中发现很多有用的信息。其中的注释对我们理解对应框架的运行机制也是很有帮助的。