天天看点

JavaWeb学习日记(三)3.DTD实际案例

DTD语法(要求不高,不要求写,要求会读)

  • 两种写法

    引入中写的:

    SYSTEM

    ,表示当前的DTD文件是本地的

    如果写的是:

    PUBLIC

    ,则表示引入的DTD文件是来自于网络的
  • 在XML内部
<?xml version="1.0" encoding="gb2312" standalone="no" ?>
<!DOCTYPE bookstore[
    <!ELEMENT bookstore (book+)>
    <!ELEMENT book (name,author,price)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT author (#PCDATA)>
    <!ELEMENT price (#PCDATA)>
 ]>
<bookstore>
    <book>
        <name>thinking in c++</name> 
        <author>Bruce Eckel</author>
        <price>40</price>
    </book>
    <book>
        <name>thinking in java</name> 
        <author>Bruce Eckel</author>
        <price>50</price>
    </book>
</bookstore>

           

浏览器调试如下:

JavaWeb学习日记(三)3.DTD实际案例

- 从外部引入

参考上一篇文章
           
DTD元素的组合类型:

DTD中这样规定:

<!ELEMENT 家庭(人+,家电*)>           
  • 1

这个DTD规定了家庭元素中可以有1到多个”人”这个子元素,也可以有0到多个”家电”这个子元素。其中的加号”+”和星号”*”的含义与正则表达式中的含义一致。

XML这样写:

<家庭>
    <人 名字="张晓明" 性别="男" 年龄="25"/>
    <人 名字="李小钢" 性别="男" 年龄="36" 爱好="作个教育家和伟人"/>
    <家电 名称="彩电" 数量="3"/>
</家庭>           
  • 1
  • 2
  • 3
  • 4
  • 5

关于组合类型,有下述的的修饰符可以使用:

符号 用途 示例 示例说明
() 用来给元素分组 (古龙|金庸),(王朔|余杰) 分成两组
| 在列出的对象中选择一个 (男人|女人) 表示男人或者女人必须出现,两者至少选其一
+ 该对象必须出现一次或者多次 (成员+) 表示成员必须出现,而却可以出现多个成员
* 该对象允许出现0次或者多次 (爱好*) 爱好可以出现两次到多次
? 该对象必须出现0次或者1次 (菜鸟?) 菜鸟可以出现,也可以不出现,如果出现的话,最多只能出现一次
, 对象必须按指定的顺序出现 (西瓜,苹果,香蕉) 表示西瓜、苹果、香蕉必须出现,并且按这个顺序出现

2.4 属性定义

DTD中属性的定义(attribute)是这样的:

<!ATTLIST 元素名称
    属性名称 类型 属性特点
    属性名称 类型 属性特点......  
>           
  • 1
  • 2
  • 3
  • 4

其中,属性的类型有下面5种:

(1) CDATA

(2) ID

(3) IDREF/IDREFS

(4) Enumerated

(5) ENTITY/ENTITIES

属性的特点有如下4种:

(1) #REQUIRED,表示这个属性必须给,不给就报错

(2) #IMPLIED,表示这个属性可以给也可以不给

(3) #FIXED value,表示这个属性必须给一个固定的value值

(4) Default value,表示这个属性如果没有值,就分配一个默认的value值

比如,我们想在学生这个子元素上加上地址这个属性,而且这个属性是必须的,示例如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE 班级 SYSTEM "myClass.dtd">
<班级>
    <学生 地址="香港">
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>   
    <学生 地址="澳门">
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   
</班级>                  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这个时候相应的DTD文件也要更新,不然就会报错,如下:

<!ELEMENT 班级 (学生+)>
<!ELEMENT 学生 (名字,年龄,介绍)>
<!ATTLIST 学生
    地址 CDATA #REQUIRED
>
<!ELEMENT 名字 (#PCDATA)>
<!ELEMENT 年龄 (#PCDATA)>
<!ELEMENT 介绍 (#PCDATA)>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.4.1 对于属性类型的详细解释

(1)属性类型-CDATA,表示属性值可以是任何字符(包括中文和数字)

<!ATTLIST 木偶
    姓名 CDATA #REQUIRED
>           
  • 1
  • 2
  • 3
<木偶 姓名="匹诺曹"/>
<木偶 姓名="PiNuocao"/>
<木偶 姓名="123"/>           
  • 1
  • 2
  • 3

(2)属性类型-ID,表明该属性的取值必须是唯一的,但是属性的值不能是以数字开头!

<!ELEMENT 公司职员 ANY>
<!ATTLIST 公司职员
    编号 ID #REQUIRED
    姓名 CDATA #REQUIRED
>           
  • 1
  • 2
  • 3
  • 4
  • 5
<公司职员 编号="Z001" 姓名="张三"/>
<公司职员 编号="Z002" 姓名="李思"/>           
  • 1
  • 2

(3)属性类型-IDREF/IDREFS

- IDREF属性的值指向文档中其它地方声明的ID类型的值

- IDREFS同IDREF,但是可以具有由空格分开的多个引用。

<!ELEMENT 家庭(人+)>
<!ELEMENT 人 EMPTY>
<!ATTLIST 人
    relID ID #REQUIRED
    paraentID IDREFS #IMPLIED
    name CDATA #REQUIRED
>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
<家庭>
    <人 relID="P_1" name="爸爸"/>
    <人 relID="P_2" name="妈妈"/>
    <人 relID="P_3" parentID="P_1 P_2" name="儿子"/>
</家庭>           
  • 1
  • 2
  • 3
  • 4
  • 5

(4)属性类型-Enumerated,事先定义好一些值,属性的值必须在所列出的值的范围内。

<!ATTLIST person
    婚姻状态 (single|married|divorced|widowed) #IMPLIED
>
<!ATTLIST person
    性别 (男|女) #REQUIRED
>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(5)属性类型-ENTITY,实体

实体定义:

- 实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。

- 在DTD定义中,一条!ENTITY语句用于定义一个实体。

- 实体可分为两种类型:引用实体和参数实体。引用实体是被XML文档应用的,而参数实体是被DTD文件本身应用的。

①引用实体:

  • 引用实体主要在XML文档中被应用

    语法格式如下,引用实体的定义内容最好放在DTD文件的最后。

<!ENTITY 实体名称 "实体内容">           
  • 1
引用方式:&实体名称; 末尾要带上分号,这个引用将直接转变成实体内容

举例如下:

<!ENTITY copyright "I am a programmer">
....
&copyright;           
  • 1
  • 2
  • 3

②参数实体:

参数实体被DTD文件自身使用

语法格式为:

<!ENTITY % 实体名称 "实体内容">           
  • 1
引用方式为:%实体名称

举例:

<!ENTITY % TAG_NAME "姓名|EMAIL|电话|地址">

<!ELEMENT 个人信息 (%TAG_NAME;|生日)>
<!ELEMENT 客户信息 (%TAG_NAME;|公司名)>           
  • 1
  • 2
  • 3
  • 4

3.DTD实际案例

学习DTD的目标在于:

(1)要求我们能够看得懂DTD文件,

(2)我们可以根据给出的DTD写出对应的XML文件

下面我们看一个案例,下述的DTD文件是从W3School在线教程中的DTD案例中拿过来的,细看每一行,我们都应该能够看得懂。

<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "[email protected]">

<!ELEMENT CATALOG (PRODUCT+)>

<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">

<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>

<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte" 
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">

<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>

<!ELEMENT NOTES (#PCDATA)>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

然后我们可以根据该DTD编写如下最简单的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE CATALOG SYSTEM "product.dtd">
<CATALOG>
    <PRODUCT NAME="康帅傅矿泉水" CATEGORY="Table" PARTNUM="12" PLANT="Chicago">
        <SPECIFICATIONS WEIGHT="20" POWER="18">这里是细节</SPECIFICATIONS>
        <PRICE>25</PRICE>
        <PRICE>28</PRICE>
    </PRODUCT>
</CATALOG>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后我们用Microsoft.XMLDOM校验该XML,会发现没有任何错误。但是要注意编码。

继续阅读