1 / 64

DTD 和 XML Schema

DTD 和 XML Schema. 第 3 章. DTD 和 XML Schema. 3.1 DTD 3.2 XML Schema 3.3 XML Schema 和 DTD 的区别. 3.1 DTD. 3.1.1 DTD 简介 3.1.2 DTD 的存在方式 3.1.3 XML 元素的声明 3.1.4 DTD 的属性声明 3.1.5 DTD 的实体声明与引用. 3.1.1 DTD 简介. Document Type Definition 文档类型定义 DTD 是一套关于关于标记的语法规则,详细地描述一组 XML 文档的结构。

finn
Download Presentation

DTD 和 XML Schema

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DTD和XML Schema 第3章

  2. DTD 和XML Schema • 3.1 DTD • 3.2 XML Schema • 3.3 XML Schema 和DTD的区别

  3. 3.1 DTD • 3.1.1 DTD简介 • 3.1.2 DTD的存在方式 • 3.1.3 XML元素的声明 • 3.1.4 DTD的属性声明 • 3.1.5 DTD的实体声明与引用

  4. 3.1.1 DTD简介 • Document Type Definition 文档类型定义 • DTD是一套关于关于标记的语法规则,详细地描述一组XML文档的结构。 • DTD文件严格地规定了将以它为标准的所有实例XML文档的树状层次结构的全部细节。 • 对XML文档的有效性验证是可选的 • 对文档有效性验证会降低系统的性能 • 使用DTD对XML文档进行有效性验证将限制其扩展性

  5. 3.1.2 DTD的存在方式 • DTD语句也称DTD声明,它使用一套与XML完全不同的语法规则进行编写。 • 内部DTD:存在于XML文档本体中元素、属性或实体的DTD声明 • 以”<! DOCTYPE”开始,以”]>”结束 • DOCTYPE是DTD的关键字,必须大写 • 外部DTD:对XML元素和属性等的声明包含在一个单独的DTD文件中。 • 方便共享 • SYSTEM引用:主要用于一个作者或组织所编写的众多XML文档中通用的DTD • PUBLIC引用:引用公开给公众使用的DTD • 内部DTD和外部DTD结合使用

  6. 3.1.3 XML元素的声明 • 示例 内部DTD <?xml version="1.0" standalone="yes"?> <!DOCTYPE REGARD [ <!ELEMENT REGARD (#PCDATA)> ]> <REGARD> HelloXML! </REGARD>

  7. 3.1.3 XML元素的声明 • 列出元素 • 要为一个文档创建适当的DTD,第一步是了解用DTD中定义的元素编码的信息结构。 • 所编写的DTD要为每个元素作元素声明。每一元素声明列出元素名和它的子元素。 • 清单:需要编写DTD结构完整的XML文档 3-1.doc • 表:学生成绩统计中的元素 表3-1.doc

  8. 3.1.3 XML元素的声明 • 在合法的XML文档中使用的每项标记都要在DTD中的元素声明中加以声明。一项元素声明指明了元素名称和元素可能的内容。 • 元素声明的基本语法: <!ELEMENT 元素名称 元素内容描述> • ELEMENT是DTD的关键字,必须大写 • 元素名:命名规则与标记的命名规则同 • 元素内容描述:规定该元素将包含哪些子元素及子元素之间的顺序,或者对于不包含子元素的元素定义其数据类型。

  9. 3.1.3 XML元素的声明 • 空元素类型 • ANY元素类型 • 父元素类型 • 只包含文本的元素类型

  10. 1、 空元素的声明 • 即没有内容的元素 • <!ELEMENT 元素名 EMPTY> • 例如:<!ELEMENT HR EMPTY> 这样,在XML文件中,就可以使用一个空元素<HR/>。

  11. 2、ANY元素类型 • 是XML为某些结构性比较差的元素提供的说明方法,它对该元素不作限制。 • 可以包含任何在该DTD中声明过的子元素 • 这些子元素的出现次数与次序不作限制 • 可以包含文本数据,即(#PCDATA)型数据 • 数据内容与子元素可以交错出现 • 语法: <!ELEMENT 元素名 ANY> • 例如:<!ELEMENT SEASON ANY> 关键词ANY(也要区分大小写)表明所有可能的元素以及可解析的字符数据都可以是SEASON元素的子元素。 • 对于根元素特别是未结构化的文档,使用ANY常见,但在其他大多数情况下,尽量避免使用。

  12. 4.只包含文本的元素类型 • 元素的内容完全是文本形式的元素类型 • 例如:<!ELEMENT YEAR (#PCDATA)> 该声明说明YEAR只能包含可析的字符数据,即非标记文本,但它不能包含自己的子元素。所以,下面这个YEAR元素是合法的: <YEAR>1998</YEAR>; 不合法: <YEAR> <MONTH>January</MONTH> <MONTH>February</MONTH> </YEAR>

  13. 3.父元素类型 • XML文档本身通过元素之间的嵌套关系描述了数据(元素)之间的树状结构关系。 • 子元素声明中包括: • 子元素名称 • 子元素出现的次数及次序 • 见下图:结构符合的具体描述 • 一个元素的各个子元素之间可以以任意顺序出现,也可以强制遵循一定的顺序。 • 不要求顺序的子元素

  14. 3.父元素类型 考虑下面的DTD定义: <!ELEMENT 联系人(姓名 EMAIL)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> 遵从这个DTD的XML文件可以为: 同样,下面这个XML文件也是有效的: <联系人>    <EMAIL>zhang@aaa.com</EMAIL>    <姓名>张三</姓名></联系人> 在DTD定义中仅仅用空白符分隔了元素“联系人”的两个子元素,这说明并没有严格要求两个元素出现的顺序,因此上面两种写法都是允许的。 <联系人> <姓名>张三</姓名>   <EMAIL>zhang@aaa.com</EMAIL> </联系人>

  15. 3.父元素类型 • 要求顺序的子元素 • 在上面例子中,如果我们使用逗号“,”来分隔两个子元素,那么XML文件中,元素“姓名”就必须出现在元素“EMAIL”前面。也就是说,如果我们把DTD定义为下面的形式: • <!ELEMENT 联系人(姓名, EMAIL)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)>

  16. 3.父元素类型 那么下面的文件是有效的: <联系人><姓名>张三</姓名><EMAIL>zhang@aaa.com</EMAIL> </联系人> 而下面这个文件不是有效的,因为它把元素“EMAIL”放在了元素“姓名”之前,这是不合规定的: <联系人>    <EMAIL>zhang@aaa.com</EMAIL>    <姓名>张三</姓名></联系人>

  17. 3.父元素类型 • 重复元素 <!ELEMENT 联系人(姓名,EMAIL+)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> 它说明一个“联系人”元素中必须含有一个“姓 名”元素,后面接一个或多个“EMAIL”元素。 <联系人>    <姓名>张三</姓名></联系人> 这个片段不是有效的,因为它没有“EMAIL”元素,而“+”代表了“一个或多个”。如果你需要表示“零个或多个”,那么应该使用字符“*”。 这样,下面的这段XML文件是“有效的”。 <联系人>    <姓名>张三</姓名>    <EMAIL>zhang@aaa.com</EMAIL>    <EMAIL>zhang@hotmail.com</EMAIL>    <EMAIL>zhang@yahoo.com</EMAIL></联系人>

  18. 3.父元素类型 • 成组元素:子元素可以使用括号并为一组。 • 下面的DTD片段说明,一个“联系人”元素中可以有一个或多个“姓名/EMAIL”子元素对,并且在每个子元素对中,“姓名”都放在“EMAIL”之前。 <!ELEMENT 联系人(姓名,EMAIL)+> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)>

  19. 3.父元素类型 • 符合这个DTD的XML文件可以是: <联系人> <姓名>张三</姓名> <EMAIL>zhang@aaa.com</EMAIL> <姓名>李四</姓名> <EMAIL>li@bbb.org</EMAIL> <姓名>王五</姓名> <EMAIL>wang@ccc.org</EMAIL></联系人> • 注意,仅仅是因为“+”由括号里面移到括号外面,元素“联系人”的内容就大大不同了。

  20. OR或 • 符号“|”描述了一个OR操作。 • 因此,下面的DTD片段所规定的XML元素是:所有的“联系人”元素应该有一个“姓名”子元素,同时,在此之后还应该有一个“电话”或一个“EMAIL”元素,但不能同时有“电话”和“EMAIL”两个元素。 <!ELEMENT 联系人(姓名,(电话|EMAIL))> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT 电话(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)>

  21. OR或 <联系人> <姓名>张三</姓名> </联系人> 这个例子是一个“无效的”XML片段,因为DTD中规定或者有一个“电 话”元素,或者有一个“EMAIL”元素,但上面这个例子中两种元素都 没有。 <联系人>    <姓名>张三</姓名>    <电话>12345678</EMAIL>    <EMAIL>zhang@yahoo.com</EMAIL></联系人> 同样,这个例子仍是一个“无效的”XML片段,因为它既有“电话”元素,又有“EMAIL”元素。

  22. OR或 一个符合上述DTD定义的“有效的”XML文件的定义应该是: <联系人> <姓名>张三</姓名> <电话>12345678</EMAIL></联系人> 或者是: <联系人> <姓名>张三</姓名> <EMAIL>zhang@yahoo.com</EMAIL> </联系人> 注意:在一个组中,只允许使用一种连接符(例如“,”或“|”)。因 此,象下面这样定义的DTD是不合法的: <!ELEMENT 联系人(姓名,电话|EMAIL)> 要想使用多种连接符,只有通过创建子组的方式,使用 <!ELEMENT 联系人(姓名,(电话|EMAIL))>

  23. 可选子元素 字符“?”说明一个子元素是可选的,它可以出现,也可以不出现。 因此,在下面的DTD中,我们规定,每一个“联系人”都必须有一个 “姓名”子元素,同时或者有一个“电话”子元素,或者有一个“EMAIL” 子元素,此外,它还可以包含一个“地址”子元素,也可以不包含这 种元素。 <!ELEMENT 联系人(姓名,(电话|EMAIL),地址?)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT 电话(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> <!ELEMENT 地址(街道,城市,省份)> <!ELEMENT 街道 (#PCDATA)> <!ELEMENT 城市 (#PCDATA)> <!ELEMENT 省份 (#PCDATA)>

  24. 可选子元素 下面的XML片段是“有效的”: <联系人><姓名>张三</姓名> <EMAIL>zhang@aaa.com</EMAIL> <地址> <街道>五街1234号</街道> <城市>北京市</城市> <省份>北京</省份> </地址> </联系人> 同样,下面这段不包含“地址”元素的XML片段也是“有效的”: <联系人>    <姓名>张三</姓名>    <EMAIL>zhang@aaa.com</EMAIL></联系人>

  25. 混合内容 • 一个元素中既希望包含子元素,也希望包含纯文本。XML中允许这种使用方法,并把这种元素称为混合内容的元素。 • 在下面的例子中,“联系人”就是一个混合元素。

  26. 混合内容 <?xml version = “1.0” encoding=“GB2312” standalone = “yes”?><!DOCTYPE 联系人列表 [ <!ELEMENT 联系人列表 (联系人)*> <!ELEMENT 联系人(姓名|电话|EMAIL|#PCDATA)*> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT 电话(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> ]> <联系人列表> <联系人> <姓名>张三</姓名> <电话>(010)62345678</电话> <EMAIL>zhang@aaa.com</EMAIL>这是关于张三的信息</联系人> </联系人列表> 注意,由于在“(姓名|电话|EMAIL|#PCDATA)”之外有“*”,所以在元素 “联系人”中可以包含零个或多个“姓名”、电话、EMAIL和纯文本字段。

  27. 小结 • 除了根元素外,在定义其它元素时使用关键字ANY都是不好的习惯。一般来说,在写一个XML文件时需要严格遵循DTD的规则,这时,一个定义明确的DTD,虽然表面上似乎充满了条条框框,但实际上会使你在书写XML文件时有规可循,反而方便了你的工作和语法分析器的工作。相反,一个在元素定义中充满了ANY的DTD,反而可能会搞得你不知所措,一头雾水。 • 不能对不同的元素使用相同的元素名,即便这些元素的内容、包含的子元素不同也不行,因为它只会引起文件各个元素的混淆,使文件的可读性大打折扣。

  28. 小结 • 定义元素时,顺序是无关紧要的。因此<!ELEMENT 姓名(#PCDATA)> <!ELEMENT 联系人列表 ANY> <!ELEMENT 联系人(姓名)>和<!ELEMENT 联系人列表 ANY> <!ELEMENT 联系人(姓名)> <!ELEMENT 姓名(#PCDATA)>所定义的文件结构是完全相同的。

  29. 小结 • 元素名的第一个字母必须是字母、或下划线(_)、或冒号(:),后跟字母、数字、句号(.)、冒号、下划线、连结号(-)的组合,并且不能包含空白符,不能以“xml”开头。 • 另外,尽管元素的第一个字母使用冒号是合法的,但最好避免这样做,因为它会引起混淆。 • 需要注意的是,尽管XML1.0标准允许使用任何长度的文件名,但是实际的XML处理器常常会限制标记名的长度。

  30. 习 题 1.何谓DTD?在XML文件中使用DTD有何好处? 2.在合法的XML文档中使用的每项标记都要在DTD中的元素声明中加以声明,请简述以下几种声明方式: 序列;零或多个子元素零;选择。

  31. 习 题(续) 3.请撰写一个实际XML文件来说明引用底下的DTD? <?xml version=”1.0”?> <!ELEMENT book (title,author,breakline,publish,price,language)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT publish (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT language (#PCDATA)> <!ELEMENT breakline EMPTY>

  32. 习 题(续) 4.请撰写一个实际XML文件来说明下面的DTD? <? Xml version = “1.0” encording = “GB2312”?> <!DOCTYPE 汽车[ <!ELEMENT 汽车(品牌,车主,保险公司*,银行贷款?,维修地点)〉 <!ELEMENT 品牌(#PCDATA)〉 <!ELEMENT 车主(#PCDATA)〉 <!ELEMENT 保险公司(#PCDATA)〉 <!ELEMENT 银行贷款(#PCDATA)〉 <!ELEMENT 维修地点(#PCDATA)〉 ]>

  33. 3.1.4 DTD的属性声明 • 开始标记和空标记可包含由等号“=”分割开的成对的属性名和属性值 • 属性包含有关元素内容信息,而不是元素内容本身。 • 元素可具有多个属性 • 结束标记不能带属性

  34. 3.1.4 DTD的属性声明 • 属性是XML提供的描述元素某些性质的信息。 • 在一个有效的XML文档中,属性要经过DTD的属性说明。 • 在DTD声明中,属性的声明语法为: <!ATTLIST 元素名 属性名 属性类型 属性默认值类型> • 元素名为属性所属的元素的名称 • 属性类型是对属性值的约束

  35. 3.1.4 DTD的属性声明 • 例如: <商品 类型 =“服装” 颜色 = "黄色"> 元素名是“商品”;属性名是属性的命名, “类型”和“颜色”是属性名;默认值说明在XML文件中,如果没有特别说明属性的取值,语法分析器默认它具有的取值;属性类型则用来指定该属性是属于有效属性类型中的哪种类型。 • 注意:由于ATTLIST是一个属性的列表,它可以包含很多属性,在实际应用中,一个元素也经常有多个属性。

  36. 属性默认值类型 • #IMPLIED:属性值可有可无的属性,而且也无须在DTD中为该属性提供缺省值。 • 语法:<!ATTLIST 元素名称 属性名称 #IMPLIED> • 有时用户在不强制指定特定默认值的情况下省略特定属性值。 • 例如,可以拥有一个SHIRT(衬衣)元素,其具有一个声明为NMTOKEN的SIZE属性。但有些衬衫属于均码,没有尺寸。可以省去SIZE这个值,并且处理器隐含这个衬衫属于均码, <!ATTLIST SHIRT SIZE NOTOKEN #IMPLIED > <SHIRT>---符合上述定义 <SHIRT SIZE=“”>---不符合上述定义

  37. 属性默认值类型 • #REQUIRED:必须赋值的属性 • 关键字REQUIRED说明XML文件中必须为这个属性给出一个属性值。 • 与提供默认值相反的情况,文档类型设计者需要强制作者选择一个值。如果属性值既重要又无法可靠地默认确定,那么设计者可以要求作者用该属性默认值来指定。 • 例如:<!ATTLIST IMAG URL CDATA #REQUIRED> 这种情况下,DTD设计者使URL属性在所用IMAG元素上都成为必需。之所以这样做是因为如果没有一个URL定位图像文件,则此IMAGE元素没有任何意义。

  38. 属性默认值类型 • #FIXED:表明该属性一定要出现,且固定为特定值,不许用其他值。 • 当需要为一个特定的属性提供一个缺省值,并且不希望XML文件的编写者把你的缺省值替代掉。这时候,就可使用FIXED关键字,同时为该属性提供一个缺省值。 • 特定属性值表明该属性的默认值,当XML文档中没有显式给出该属性的取值时,取此值。当该属性的取值已经显式地给出,则为给出值。 • 如果不使用上面任何一种关键字的话,该种属性就是属于这种类型。对于这种属性,你需要在DTD中为它提供一个缺省值。而在XML文件中可以为该属性给出新的属性值来覆盖事先定义的缺省值,也可以不另外给出属性值,后一种情况下它就默认为采用DTD中给出的缺省值。

  39. 属性类型

  40. 属性类型 (1)CDATA类型:是最简单的属性类型,也是约束最少的属性类型。即CharacterData 缩写,代表该属性值为一般的文字,除此没有其它限制. • 语法: <!ATTLIST 元素名称 属性名称 CDATA 属性默认值类型> • 例如: <?xml version = "1.0“ encoding="GB2312" standalone = "yes"?><!DOCTYPE 剧本 [ <!ELEMENT 剧本 ANY> <!ELEMENT 对话 (#PCDATA)> <!ATTLIST 对话 演员 CDATA> ]> <剧本> <对话 演员=“某甲”>我可不这么认为!</对话> <对话 演员=“某乙”>为什么呢?</对话> </剧本>

  41. 属性类型 (2)枚举型:列举了该属性所能取得的全部值. • 语法: <!ATTLIST 元素名称 属性名称 (可选属性值1|可选属性值2|……|可选属性值N) 属性默认值类型> • 例如: <?xml version = “1.0”encoding=“GB2312”standalone = “yes”?><!DOCTYPE 购物篮 [ <!ELEMENT 购物篮 ANY> <!ELEMENT 肉 EMPTY> <!ATTLIST 肉 类型( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) “鸡肉”> ]> <购物篮> <肉 类型 = “鱼肉”/> <肉 类型 = “牛肉”/> <肉/> </购物篮> 注意,在上面这个例子中,给属性“类型”定义的缺省值是“鸡肉”,所以“购 物篮”中的第三个元素的“类型”属性取值为“鸡肉”。

  42. 属性类型 (3)NMTOKEN和NMTOKENS类型:一个有效的XML名称,必须以字母或者下划线开始,之后是字母、数字下划线、短横线或圆点,而且不能包含空格。 后者表明属性值可能由若干个满足NMTOKEN属性要求结合在一起形成的,即多个NMTOKEN之间可能存在空格。 • 语法: <!ATTLIST 元素名称 属性名称 NMTOKEN|NMTOKENS 属性默认值类型>

  43. 属性类型 • 例如1: <!ATTLIST Employee security_level NMTOKEN #REQUIRED> <Employee security_level=“trusted”> • 上述代码表示元素E m p l o y e e有一个名为s e c u r i t y _ l e v e l的属性,其值符合X M L名称记号的规则。我们可以用它来控制对机密文档的访问。由于定义属性列表时使用了N M TO K E N,而不是枚举类型,文档创作者只需创建新的值,就能够适应新的安全级别要求,而不必每次都编辑D T D。只要符合我们前面介绍的有效的N M TO K E N值应该遵守的规则任何值都可以作为这种属性的值。

  44. 属性类型 • 例如2: <!ATTLIST Employee security_compartments NMTOKENS #IMPLIED> <Employee security_compartments=“red green mega ultra ”> 这个职员能够访问名为r e d、g r e e n、m e g a和u l t r a的安 全区域。就类型而言,这些都是有效的N M TO K E N值。与枚举类型 不同,解析器不检查这些值的有效性。文档的作者必须确保自己使 用了适当的名称。

  45. 属性类型 • 例如3: <!ELEMENT 数据(#PCDATA)> <!ATTLIST 数据 安全性( ON | OFF ) "OFF“ 授权用户 NMTOKENS #IMPLIED > Xml文件: <数据 安全性="ON" 授权用户 = "IggieeB SelenaS GuntherB">blah blah blah </数据>

  46. 属性类型 • NMTOKEN属性类型 • NMTOKEN属性类型限定属性值为有效的XML名称。 • 当需要从大量名字中选取不是XML的规定部分但与XML命名要求相符的名字时,就能体现NMTOKEN的用途。

  47. 属性类型 • NMTOKENS属性类型 • NMTOKENS属性类型几乎就是NMTOKEN的复数形式。这种类型的属性可以使如下情况合法——属性由若干XML名称字组成,彼此间由空格分隔。通常可为使用NMTOKEN属性相同的理由而使用NMTOKENS属性,但仅仅在需要多个名字的时候。

  48. 属性类型 (4)ENTITY和ENTITIES类型:当属性值是一个外部实体的引用时,用ENTITY来说明属性类型。 一般来说,当属性值是一个内部实体引用时,将属性类型声明为CDATA即可。 • 实体属性类型 • 实体类型的属性值属于一般实体,如前所述,它的定义方式是: <!ENTITY 实体名 “实体内容”> 或利用SYSTEM定义外部实体,方式为: <!ENTITY 实体名 SYSTEM “外部文件名”> • 引用方式为: &实体名; 使用关键字ENTITY,则声明一个属性是实体类型,它的取值为已定 义的实体。请看下面例子:

  49. 属性类型 <?xml version = "1.0" encoding="GB2312“ standalone = "yes"?><!DOCTYPE 文件[ <!ELEMENT 文件 ANY> <!ELEMENT 电影 EMPTY> <!ATTLIST 电影 来源 ENTITY #REQUIRED> <!ENTITY pic SYSTEM “1-5.jpg"> ]><文件> <电影 来源 = "pic"></文件>

More Related