Schema & DTD
这两项技术都是用来定义XML文档结构的。一个文档满足了XML文档格式规定才算是一个XML文档,但是随便一个XML文档其实对我们意义不大,因为XML并不是为哪项特定应用而设计的,其结构也千变万化,所以我们必须规定XML文档的结构以便我们创建,解析和交换XML文档。使用这两项技术我们就可以规定文档结构,并且在必要的时候对文档进行验证,这也是基于XML的数据传输的基本要求。(怎么样有些“协议”的意味吧J,在以后我会继续给大家分析基于XML的协议。)
DTD是Document Type Definition的缩写。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>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
这是一个完整的XML文档prolog部分中黄色部分就是一个内部DTD。
如果你不想把结构信息包含在数据文件里那么可以把黄色的部分换成对外部DTD文档的引用:
<!DOCTYPE note SYSTEM "note.dtd">
这句指名了文档结构在note.dtd里定义,而note.dtd的内容是这样的:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
大家可以看到内容跟内部DTD是一样的。
下面具体来看看DTD的构思和一些通常的用法:
在DTD看来,一个XML文档是由好多结构块(building blocks)组成的。
DTD里面的结构块:
l Elements
<message>some message in between</message>
这就是一个元素,element是组成XML的主要成分。
常用写法:
<!ELEMENT element-name EMPTY> 空element比如:<br />
<!ELEMENT element-name ANY> 包含任何内容的element,前提是内容合法。
<!ELEMENT element-name (#PCDATA)> 只含有字符信息的element。
<!ELEMENT element-name (child-element-name,child-element-name,.....)> 包含若干子element的element。注意,子节点必须按照这里定义的顺序出现。
下面是关于出现次数的一些写法:
<!ELEMENT element-name (child-name)> 子节点出现且只出现一次。
<!ELEMENT element-name (child-name+)> 一次或者多次。
<!ELEMENT element-name (child-name*)> 零次或者多次。
下面是一些组合用法:
<!ELEMENT note (to,from,header,(message|body))> “|”用法提供“或”的功能。
<!ELEMENT note (#PCDATA|to|from|header|message)*> 这句的意思是note元素可以包含零个或者多个(#PCDATA|to|from|header|message)中任意的一个元素或文本。
l Attributes
属性是用来对元素的附加特性进行描述,他以名值对的形式出现。如:
<img src="computer.gif" />
下面是属性的表示方法:
<!ATTLIST element-name attribute-name attribute-type default-value>
Attribute Types:
Value |
Explanation |
CDATA |
文本 |
(en1|en2|..) |
规定属性值必须是列表中的一个 |
ID |
属性值必须唯一 |
IDREF |
属性值是另外一个element的ID |
IDREFS |
属性值是一个ID列表 |
NMTOKEN |
属性值是一个合法的XML name |
NMTOKENS |
属性值是一个合法的XML name列表 |
ENTITY |
属性值是一个entity |
ENTITIES |
属性值是一个entity列表 |
NOTATION |
属性值是一个notation |
xml: |
属性值是一个预定义xml value |
Default Value:
Value |
Explanation |
value |
默认值 |
#REQUIRED |
属性是必须的 |
#IMPLIED |
属性是可选的 |
#FIXED value |
属性是固定值的 |
那么假如我们想要规定payment元素的一个叫做type的属性,他必须是check或者cash,而且默认是cash,我们需要这样写:
<!ATTLIST payment type (check|cash) "cash">
l Entities
Entity References |
Character |
< |
< |
> |
> |
& |
& |
" |
" |
' |
' |
这个不用多说了J。在HTML里我们不是常用 么,哈哈。
但是值得一提的是entity可以自定义J,上面的不过是XML预定义的而已。
Entity的定义既可以是内部的,也可以是外部的。
内部定义:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright W3Schools.">
这两行定义了两个entity,下面是在XML文档里的引用
<author>&writer;©right;</author>
外部定义:
<!ENTITY writer SYSTEM "http://www.w3schools.com/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3schools.com/dtd/entities.dtd">
这里定义了两个外部entity,但是不影响引用。
<author>&writer;©right;</author>
有些像宏定义,不是么?
l PCDATA
Parsed character data。
PCDATA在经过XML解释器的时候会被解析,其中的标签和Entity都会被按照XML的规定解释。
比如<body>会被认为是一个element的开始,而一个&会被解释为&。
l CDATA
与PCDATA相对的一种用法,里面的字符保持原样,不会被解释器解释。
不知道大家有没有一种感觉——DTD写在XML文档里总有些不伦不类的感觉。原因何在呢——DTD本身不是基于XML的。所以很自然我么有了XML Schema。
XML Schema是基于XML的,他的使命就是用来代替DTD,实际上它比DTD还要强大。
照例我们在这里给一个感性的认识: