今天在查看关于如何构建commonmark.js的AST时接着发现有必要好好了解一下DTD。说来真惭愧,同学的创新项目当初信誓旦旦要努力做,但是总是从没好好静下心来认真做过,结果全是担任组长的同学一个人辛辛苦苦完成的,而我却把大部分的时间又情不自禁地像高中那样用来死读书。。。但是说来也可笑,现在我正因为自己的死读书而有机会现在能够坐在研究生的实验室里。。。。 所以,现在课也几乎没多少了,自己又多了一个自习室和一台台式电脑,绝对没理由再继续不负责任了。。所以,我一定要好好地写博客,好好地提升自己。
算了,也写一下这几天的收获吧。MarkDown,刚开始从qq上看到这个单词的时候。真心感觉自己落后同学好多好多好多好多好多惹。。一瞬间真心感觉他对自己还有信心呢。太不可思议了。。于是当天晚上查阅资料,全是英文的,虽然说自己的英文水平不是算差的,但是就是看这种关于学术性的文章感觉头大,说白了就是对术语知之甚少。。再说深一点,就是自己记忆力不好,这不是搪塞的借口,确实是这样。当我高中时第一次得知自己患有鼻炎的时候,以为只是小毛病,没想到医生很严肃的告诉我不简单,会影响记忆力。。。哎,而且这病永远也治不好,直到现在我还丢三落四,比如说今天,忘拿东西一共回了宿舍3次,都差不多快接近目的地的时候才想起来忘记了。。。怎么感觉我越扯越远呢。。。
好了,以下的内容都是从w3school网站上看来的,也有自己写的部分啦,虽然不多。
DTD(Document Type Definition)是用来定义合法的XML文档构建模块,使用一系列合法的元素来定义文档之结构,DTD可悲成行地声明再XML文档中,也可作为一个外部应用。
C1 内部DOCTYPE声明
如果DTD被包含在XML源文件中,使用下列的语法来被包装在一个DOCTYPE引用中。
<!DOCTYPE 根元素 [元素声明]>
带有DTD的XML文档实例。
<?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>Gergo</to> <from>John</from> <heading>Reminder</heading> <body>Do not forget the meeting!</body> </note>
显示效果:
<note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
对上面DTD的解释如下:
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。
!ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"
!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型
!ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型
!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型
C2外部文档声明
如果DTD位于XML源文件的外部,那么就可以通过以下的方式被封装在一个DOCTYPE定义中
<!DOCTYPE 根元素 SYSTEM “文件名”>
C3为何使用DTD
1.通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述。
2.通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
3.自己的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
4.还可以使用 DTD 来验证来自自身的数据。
C4XML文档构建模块
所有的XML文档和HTML文档都由以下简答的构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
1)元素
是主要的构建模块。在HTML中的例子是"body""table"(在html是称作标签);在XML中的例子是"note","message".元素可包含文本或者其他元素,或者为空。(html中的空标签是hr,br,img)
2)属性
提供有关元素的额外信息,一般来说都是在以元素的开始标签中声明的。
3)实体
用来定义普通文本的变量。实体引用是对实体的引用。eg: HTML 实体引用:" "。这个“无折行空格”实体在 HTML 中被用于在某个文档中插入一个额外的空格。
以下的实体现在XML中被预定义:(个人理解,就是关键字吧)
实体定义 | 字符 |
< | < |
> | > |
& | & |
" | " |
' | ' |
4)PCDATA
PCDATA(parsed character data)意思是被解析的字符数据。可把字符数据想象为XML元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
5)CDATA
CDATA(character data)意思是字符数据。是不会被解析的文本。总之,标签或者实体都不会被解析。
C5DTD元素
1.声明:
<!ELEMENT 元素名称 类别>
OR
<!ELEMENT 元素名称 (元素内容)>
2 空元素
通过类别关键词EMPTY来进行声明:
<!ELEMENT 元素名称 EMPTY>
eg:
<!ELEMENT br EMPTY>
在XML中:
</br>
3 只有PCDATA的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:
<!ELEMENT 元素名称 (#PCDATA)>
4 带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 元素名称 ANY>
5 带有子元素(序列)的元素
带有一个元素或者多个子元素的通过括号内的子元素名字进行声明:
<!ELEMETN 元素名称 (子元素名 )> <!ELEMENT 元素名称 (子元素名1 子元素名2)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。"note" 元素的完整声明是:
<!ELEMENT note (from,to,body,sub)> <!ELEMENT from (#PCDATA)> <!ELEMENT to (#PCDATA)> <!ELEMENT body (#PCDATA)> <!ELEMENT sub (#PCDATA)>
6 声明只出现一次的子元素
<!ELEMENT 元素名称 (子元素名称)>
7 声明至少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
8 声明出现0或者多次的子元素
<!ELEMENT 元素名称 (子元素名称*)>
9 声明出现0或者一次的子元素
<!ELEMENT 元素名称 (子元素名?)>
10 声明在多者之间选择的子元素
eg:
<!ELEMENT note (to,from,header,(message|body))>
11 声明混合型的内容
<!ELEMENT note (#PCDATA|to|from|header|message)*>
C6DTD属性
在DTD中元素的属性哦有那个过关键字“ATTLIST”来声明。
1.语法:
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
DTD实例:
<!ATTLIST payment type CDATA "check">
XML实例:
<payment type="checked"/>
以下是属性类型的选项:
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认值参数可使用下列值:
值 | 解释 |
---|---|
值 | 属性的默认值 |
#REQUIRED | 属性值是必需的 |
#IMPLIED | 属性不是必需的 |
#FIXED value | 属性值是固定的 |
2 规定一个默认的属性值:
DTD:
<!ELEMENT square EMPTY> <!ATTLIST square width CDATA "0">
XML:
<square width="100" />
在上面的例子中,"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。如果宽度没有被设定,其默认值为0 。
3.#IMPLIED
假如不希望强制作者包含属性,并且没有默认值选项的话,请使用关键词 #IMPLIED。
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #IMPLIED>
eg:
DTD:
<!ATTLIST contact fax CDATA #IMPLIED>
合法的XML:
<contact fax="222323-232" /> <contact />
4 #REQUIRED
假如没有默认值选项,但是仍然希望强制作者提交属性的话,请使用关键词 #REQUIRED。
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #REQUIRED>
5 #FIXED
如果希望属性拥有固定的值,并不允许作者改变这个值,请使用 #FIXED 关键词。如果作者使用了不同的值,XML 解析器会返回错误。
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #FIXED "value">
6 列举属性值
如果您属性值为一系列固定的合法值之一,请使用列举属性值。
语法:
<!ATTLIST 元素名称 属性名称 (en1|en2|..) 默认值>
eg:
<!ATTLIST payment type (check|cash) "cash">
C7DTD实体
1.定义:实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可在内部或外部进行声明。
2.内部实体声明:
语法:
<!ENTITY 实体名称 “实体的值”>
eg:
DTD :
<!ENTITY copyright "Copyrght ...">
XML :
<author>©right;</author>
注:一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
3.外部实体声明
语法:
<!ENTITY 实体名称 SYSTEM "URI/URI">
eg:
DTD:
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
XML:
<author>©right;</author>
C8DTD验证
1.通过XML解析器进行验证
当试图打开某个 XML 文档时,XML 解析器有可能会产生错误。通过访问 parseError 对象,就可以取回引起错误的确切代码、文本甚至所在的行。
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM") xmlDoc.async="false" xmlDoc.validateOnParse="true" xmlDoc.load("note_dtd_error.xml") document.write("<br>Error Code: ") document.write(xmlDoc.parseError.errorCode) document.write("<br>Error Reason: ") document.write(xmlDoc.parseError.reason) document.write("<br>Error Line: ") document.write(xmlDoc.parseError.line)
注:load( ) 方法用于文件,而 loadXML( ) 方法用于字符串。
2.关闭验证
通过把 XML 解析器的 validateOnParse 设置为 "false",就可以关闭验证。
3.parseError对象
see more at <XML & DOM>