html中的DOCTYPE是什么?(XML进阶之DTD)

1、问题

了解过HTML文档的都知道,在HTML文档的第一行有这么一句:

<!DOCTYPE html>

或者是这样的(HTML4.0系列的声明):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" 
"http://www.w3.org/TR/html4/frameset.dtd">

**那么这个DOCTYPE究竟是何物呢?为什么要在文档的第一行引入这个呢?**可能很多人就只知道这个是声明HTML的版本的 ,那么声明这个有什么用呢?如果仔细看HTML4.0系列的三种声明,每个里面都有一个网址的超链接,其中后缀都是dtd,我们打开其中一个网站就可以看到一篇文档,大概的意思就是在描述HTML4.0应该怎么怎么样?于是我们就迎来了今天的主角,一起看看究竟这个DTD是什么?

附原文片段:

This is HTML 4.01 Strict DTD, which excludes the presentation 
    attributes and elements that W3C expects to phase out as 
    support for style sheets matures. Authors should use the Strict
    DTD when possible, but may use the Transitional DTD when support
    for presentation attribute and elements is required.
    
    HTML 4 includes mechanisms for style sheets, scripting,
    embedding objects, improved support for right to left and mixed
    direction text, and enhancements to forms for improved
    accessibility for people with disabilities.

2、DTD是什么?

DTD全名Document Type Definition,文档类型定义,它的作用是用来定义XML文档的合法构建模块,他使用一系列的元素来定义文档结构

我们知道XML是可扩展标记语言,在XML文档中,没有说有什么固定的预定义标签,只要是符合语法的都可以。因为这种灵活性,XML成为了被用来结构化、存储或传输信息的良好工具载体。但是,正是这种灵活性,也给我们带来了问题,**既然XML中什么标签都有可能出现,我怎么能够知道别人发给我的XML文档是不是我想要的呢?**那必然就需要有一样东西能够去校验,于是就有了DTD。

当然DTD本身并不会对XML文档去做校验,DTD本身也是一个文档,它 的作用在于阐述清楚,一个合法(负责规则)的XML文档中应该有哪些元素,解析校验的工作当然还是交给特定的工具去解析DTD做文档校验的,比如浏览器。

3、DTD如何使用?

DTD本身有两种使用方式:

(1)成行地声明于XML文档中

(2)外部引用

针对第一种方式的示例:

<?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>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget learning !</body>
</note>

第二种方式我们就比较熟悉了:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

4、DTD的语法

4.1 复习XML

讲DTD之前,我们先回顾一下XML文档中都有哪些东西组成?

  • 元素(Element)
  • 属性(Attribute)
  • 实体(Entity)
  • PCDATA
  • CDATA

知道了这些之后,我们自然知道要对这些构成元素做定义声明,自然是要对这几种分别进行定义,于是同理DTD的语法中就会涉及到这几样东西。当然如果对这几个东西还有点不清楚的没关系,往下看就明白了。

4.2 DTD元素定义

在DTD中,XML的元素通过元素声明来进行

语法

<!ELEMENT 元素名称 类别>

或者

<!ELEMENT 元素名称 (元素内容)>

举个例子,我们声明一个<br/>标签

<!ELEMENT br EMPTY>

意思代表在XML文档中可以出现一个名称为br的元素,它的类型是空的。

元素类型示例总结

类型含义示例
EMPTY一个空元素<!ELEMENT br EMPTY>
(#PCDATA)只有PCDATA的元素<!ELEMENT br (#PCDATA)>
ANY带有任何内容的元素<!ELEMENT br ANY>
(en1,en2, …)带有子元素(序列)的元素<!ELEMENT my (name,age)>
(en)声明只出现一次的元素<!ELEMENT note (message)>
(en+)声明最少出现一次的元素<!ELEMENT note (message+)>
(en*)声明出现零次或者多次的元素<!ELEMENT note (message*)>
(en?)声明出现零次或一次的元素<!ELEMENT note (message?)>
(en1,(en2|en3))声明元素包含非名称2既名称3的子元素,示例中note元素必须包含to元素,以及非message元素就是body元素<!ELEMENT note (to,(message\|body))>
(en1|en2)*声明包含混合型的内容,零个或多个<!ELEMENT note (#PCDATA\|to\|from\|header\|message)*>

4.3 DTD属性定义

在DTD中,XML的属性通过ATTLIST来声明定义

语法

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

示例:

<!ATTLIST payment type CDATA "check">

对应的XML实例

<payment type="check"/>

属性类型可选项

类型描述
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 squre width CDATA "0">

4.4 DTD实体定义

实体是什么?是用于定义引用普通文本或特殊字符快捷方式变量。实体引用是对实体的引用,可在内部或者外部进行声明。单看官方的这个定义可能比较晦涩,举个例子可能就比较清晰了,&nbsp;代表一个空格字符,&gt;代表一个大于号,现在知道什么是实体了吧。

语法

<!ENTITY 实体名称 "实体的值">

示例

<!ELEMENT author writer ENTITY>
<!ENTITY writer "chengcheng">

<author>&chengcheng;</author>

4.5 DTD如何进行验证?

通过上述我们知道,DTD只是用来定义一个合法的XML是如何组成的,也就是只是展示规则,具体的验证我们还得交给相应的解析器。下面介绍利用javascript和浏览器来做XML校验,分为IE和非IE浏览器,在IE中有ActiveXObject(“Microsoft.XMLDOM”)对象可以用来解析,在非IE中可以使用DOMParser对象去解析。

IE浏览器

function validateXML(){
    var xmlDoc  = new ActiveXObject("Microsoft.XMLDOM");
    var xmlContent = "<?xml version ="1.0" encoding="utf-8" ?><!DOCTYPE book [<!ELEMENT book (cover,content)><!ELEMENT cover EMPTY><!ATTLIST cover title CDATA #REQUIRED><!ATTLIST cover desc CDATA #IMPLIED><!ELEMENT content (#PCDATA)>]><book><cover>123123</cover></book>";
    xmlDoc.async="false";
    xmlDoc.loadXML(xmlContent);

    console.log(xmlDoc);
    var errorMessage;
    var errorCode;
    if(xmlDoc.parseError.errorCode!=0)
    {
        errorMessage="错误code: " + xmlDoc.parseError.errorCode + "\n";
        errorMessage=errorMessage+"错误原因: " + xmlDoc.parseError.reason;
        errorMessage=errorMessage+"错误位置: " + xmlDoc.parseError.line;
        errorCode = 1;
    }
    else
    {
        errorMessage = "格式正确";
    }
    console.log(errorMessage);
}

非IE浏览器

function validateXML(){
    var parser=new DOMParser();
    var xmlContent = '<?xml version ="1.0" encoding="utf-8" ?><!DOCTYPE book [<!ELEMENT book (cover,content)><!ELEMENT cover EMPTY><!ATTLIST cover title CDATA #REQUIRED><!ATTLIST cover desc CDATA #IMPLIED><!ELEMENT content (#PCDATA)>]><book><cover>123123</cover></book>';
    var xmlDoc = parser.parseFromString(xmlContent,"text/xml");
    var error = xmlDoc.getElementsByTagName("parsererror");

    console.log(xmlDoc);
    var errorMessage;
    var errorCode;
    if (error.length > 0){
        if(xmlDoc.documentElement.nodeName=="parsererror"){
            /**
             * 适用于Mozilla,Firefox,Opera浏览器
             * parseFromString返回一个document对象,但这个对象的文档元素是<parseerror>
             */
            errorCode = 1;
            errorMessage = xmlDoc.documentElement.childNodes[0].nodeValue;
        } else {
            /**
             * 适用于Safari和chrome浏览器
             * 这两种浏览器返回的文档包含<parseerror>标签,但是该元素只会出现在解析错误的地方
             * 因此通过xmlDoc.documentElement.nodeName这种方式是无法正确获取是否解析错误的
             */
            errorCode = 1;
            errorMessage = xmlDoc.getElementsByTagName("parsererror")[0].innerHTML;
        }
    } else {
        errorMessage = "格式正确";
    }
    console.log(errorMessage);
}

5、结论

DOCTYPE 是用来引入DTD校验XML文档或者HTML文档是否合法的。

Reference

https://www.w3school.com.cn/dtd/index.asp

https://cloud.tencent.com/developer/article/1145099

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值