ホームページ > バックエンド開発 > XML/RSS チュートリアル > XML - XML ドキュメント制約の DTD の詳細な説明

XML - XML ドキュメント制約の DTD の詳細な説明

黄舟
リリース: 2017-02-24 15:02:10
オリジナル
1832 人が閲覧しました

1. XML ファイル制約と DTD の簡単な紹介

私たちは XML 文書の記述仕様を制約する文書を作成します。これは XML 制約と呼ばれます。

一般的に使用される制約テクノロジは次のとおりです:

  • XML DTD

  • XML スキーマ

DTD の基本概念:

ドキュメント タイプ定義

DTD ファイル一般に XML ファイルのマッチングは主に次の目的で使用されます。 XML ファイルを制限します。

XML ファイルには DTD ファイルが導入されているため、XML はタグをカスタマイズできますが、DTD ファイルによって制約されます。たとえば、前のセクションでは、XML を使用してクラスに関する情報を記述しました。各生徒の <area> タグを定義した場合、構文エラーは発生しません。意味的には正しいです。学生はそれをどのように使用できますか?現時点では、DTD ファイルを使用してこの XML を制約する必要があります。 标签,语法上也是没有错误的,但是不符合语义,学生怎么能够用面积来描述呢?这时候我们就需要用到DTD文件来约束这个XML。

<?xml version="1.0" encoding="gb2312"?><class>
    <stu id="001">
        <name>杨过</name> 
        <sex>男</sex>
        <age>20</age>
        <面积>100</面积>
    </stu></class>
ログイン後にコピー
ログイン後にコピー

1.1 DTD约束快速入门案例

基本语法:

<!ELEMENT 元素名 类型>
ログイン後にコピー
ログイン後にコピー

我们还以班级为例,编写如下DTD文件,myClass.dtd:

<!ELEMENT 班级 (学生+)><!ELEMENT 学生 (名字,年龄,介绍)><!ELEMENT 名字 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 介绍 (#PCDATA)>
ログイン後にコピー
ログイン後にコピー

第一行表示根元素为班级,并且有学生这个子元素,子元素为1或者多个。
第二行表示学生的子元素为名字,年龄,介绍
名字下面没有子元素了,那么#PCDATA表示名字里面可以放任意文本。
年龄和介绍也是类似。

编写myClass.xml文件并引入DTD文件如下:

<?xml version="1.0" encoding="utf-8"?><!--引入dtd文件,约束这个xml--><!DOCTYPE 班级 SYSTEM "myClass.dtd"><班级>
    <学生>
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>   
    <学生>
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー

引入中写的:SYSTEM,表示当前的DTD文件是本地的
如果写的是PUBLIC,则表示引入的DTD文件是来自于网络的.

这时候引入的DTD文件是没有产生作用的,如果我们在学生元素中添加子元素<面积>,打开这个XML文件,浏览器依然不会报错。

<?xml version="1.0" encoding="utf-8"?><!--引入dtd文件,约束这个xml--><!DOCTYPE 班级 SYSTEM "myClass.dtd"><班级>
    <学生>
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
        <面积>100平米</面积>
    </学生>   
    <学生>
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー

我们需要编程校验XML文档的正确性

IE5以上的浏览器内置了XML解析工具:Microsoft.XMLDOM,开发人员可以编写JavaScript代码,利用这个解析工具装载XML文件,并对XML文件进行DTD验证。

我们编写myXmlTools.html来对这个XML进行校验,如下:

<html>
    <head>
    <!--自己编写一个简单的解析工具,去解析XML DTD是否配套-->     
    <script language="javascript">
        // 创建xml文档解析器对象
        var xmldoc = new ActiveXObject("Microsoft.XMLDOM");        // 开启xml校验
        xmldoc.validateOnParse = "true";        // 装载xml文档,即指定校验哪个XML文件
        xmldoc.load("myClass.xml");
        document.writeln("错误信息:"+xmldoc.parseError.reason+"<br>");
        document.writeln("错误行号:"+xmldoc.parseError.line);    </script>

    </head>
    <body>

    </body></html>
ログイン後にコピー
ログイン後にコピー

用IE浏览器打开这个html文件,可以看到运行结果:

XML - XML ドキュメント制約の DTD の詳細な説明

可以看到第9行正是我们添加的<面积>

<!DOCTYPE 根元素 [定义内容]>
ログイン後にコピー
ログイン後にコピー

1.1 DTD 制約のクイックスタートケース

基本構文:

<!DOCTYPE 根元素 SYSTEM "DTD文件路径">
ログイン後にコピー
ログイン後にコピー
また、クラスを例として、次の DTD ファイル myClass.dtd を作成します。
<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件的URL">
ログイン後にコピー
ログイン後にコピー

最初の行は、ルート要素がこの子要素には 1 つ以上の子要素があります。

2 行目は、生徒のサブ要素が名前、年齢、紹介であることを示しています。 名前の下にはサブ要素がないため、#PCDATA は名前に任意のテキストを配置できることを示します。 年齢も紹介も似てます。

myClass.xml ファイルを作成し、次のように DTD ファイルをインポートします:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
ログイン後にコピー
ログイン後にコピー
インポートに次のように記述されます: SYSTEM、現在の DTD ファイルがローカルであることを示します

PUBLIC として記述されている場合、インポートされた DTD ファイルが

今回導入した DTD ファイルは効果がありません。サブ要素 <area> を Student 要素に追加してこの XML ファイルを開いたとしても、ブラウザーは依然としてエラーを報告しません。エラー。

うわー

XML ドキュメントの正確性を

プログラムで検証する必要があります

IE5 以降のブラウザには、XML 解析ツール Microsoft.XMLDOM が組み込まれています。開発者は、JavaScript コードを作成し、この解析ツールを使用して XML ファイルを読み込み、XML ファイルの DTD 検証を実行できます。

この XML を検証するために、次のように myXmlTools.html を作成します:
<!ELEMENT NAME CONTENT>
ログイン後にコピー
ログイン後にコピー

この HTML ファイルを IE ブラウザで開くと、実行結果が表示されます:


XML ファイル検証

9 行目は < area>< を追加したものであることがわかります。 /code> この行。

2.DTDの詳細

2.1 DTDドキュメントの宣言と参照

1. 内部DTDドキュメント

<!ELEMENT 家庭(人+,家电*)>
ログイン後にコピー

2. インポートされた外部DTDドキュメントには次の2種類があります。

(1) 参照される DTD ファイルがローカル ファイルの場合は、SYSTEM を使用して識別し、次のように「DTD ファイルのパス」を記述します。

<家庭>
    <人 名字="张晓明" 性别="男" 年龄="25"/>
    <人 名字="李小钢" 性别="男" 年龄="36" 爱好="作个教育家和伟人"/>
    <家电 名称="彩电" 数量="3"/></家庭>
ログイン後にコピー
ログイン後にコピー

(2) 参照される DTD ファイルがパブリック ファイルの場合は、PUBLIC を使用しますロゴは次のようになります:

<!ATTLIST 元素名称
    属性名称 类型 属性特点
    属性名称 类型 属性特点......  >
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

例:
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE 班级 SYSTEM "myClass.dtd"><班级>
    <学生 地址="香港">
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>   
    <学生 地址="澳门">
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
2.2 基本的な DTD 構文:
<!ELEMENT 班级 (学生+)><!ELEMENT 学生 (名字,年龄,介绍)><!ATTLIST 学生
    地址 CDATA #REQUIRED><!ELEMENT 名字 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 介绍 (#PCDATA)>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
- ELEMENT はキーワードであり、変更できません - CONTENT は要素タイプである必要があります大文字です! CONTENT のコンテンツを記述するには 3 つの方法があります: (1)EMPTY - 要素にサブ要素やテキストを含めることはできませんが、属性を持つことはできることを示します。 (2)ANY—DTD で定義された任意の要素コンテンツを要素に含めることができることを示します (3) #PCDATA - 任意の文字データを含めることができますが、その中にサブ要素を含めることはできません 2.3 DTD 要素の組み合わせタイプ:
<!ATTLIST 木偶
    姓名 CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
この DTD は、 family 要素 「人」の子要素は 1 個以上、「家電」の子要素は 0 個以上存在できます。プラス記号「+」とアスタリスク「*」の意味は、正規表現の意味と一致します。
<木偶 姓名="匹诺曹"/><木偶 姓名="PiNuocao"/><木偶 姓名="123"/>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
SymbolPurposeExampleサンプルの説明()使用する要素 (Gu Long | Jin Yong)、(Wang Shuo | Yu Jie) を 2 つのグループにグループ化しましょう リストされたオブジェクトの 1 つを選択します (Man | Woman) は男性を意味しますまたは女性 必ず表示し、2 つのうち少なくとも 1 つを選択してください+オブジェクトは 1 回または複数回表示する必要があります(メンバー+) はメンバーが必ず表示されることを意味しますが、複数のメンバーが表示される可能性があります *
ここで: - NAME は要素名を表します
これは DTD で指定されます:
XMLは次のように記述されます: 組み合わせの種類については、次の修飾子が使用できます:
🎜オブジェクトは 0 回以上出現することができます🎜🎜(趣味*)🎜🎜趣味は 2 回から複数回出現することができます🎜🎜🎜🎜?🎜🎜オブジェクトは 0 回または 1 回出現する必要があります🎜🎜(新人?) 🎜🎜 ルーキーは出現してもしなくてもよい 🎜🎜🎜🎜、🎜🎜 オブジェクトは指定された順序で出現する必要がある 🎜🎜 (スイカ、リンゴ、バナナ) 🎜🎜 はスイカ、リンゴ、バナナは必ず出現し、この順序で出現します🎜🎜🎜🎜

2.4 属性定义

DTD中属性的定义是这样的:

<!ATTLIST 元素名称
    属性名称 类型 属性特点
    属性名称 类型 属性特点......  >
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

其中,属性的类型有下面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</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

<!ELEMENT 班级 (学生+)><!ELEMENT 学生 (名字,年龄,介绍)><!ATTLIST 学生
    地址 CDATA #REQUIRED><!ELEMENT 名字 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 介绍 (#PCDATA)>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

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

<!ATTLIST 木偶
    姓名 CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
<木偶 姓名="匹诺曹"/><木偶 姓名="PiNuocao"/><木偶 姓名="123"/>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

<!ELEMENT 公司职员 ANY><!ATTLIST 公司职员
    编号 ID #REQUIRED
    姓名 CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
<公司职员 编号="Z001" 姓名="张三"/><公司职员 编号="Z002" 姓名="李思"/>
ログイン後にコピー
ログイン後にコピー

(3)属性类型-IDREF/IDREFS
- IDREF属性的值指向文档中其它地方声明的ID类型的值
- IDREFS同IDREF,但是可以具有由空格分开的多个引用。

<!ELEMENT 家庭(人+)><!ELEMENT 人 EMPTY><!ATTLIST 人    relID ID #REQUIRED
    paraentID IDREFS #IMPLIED
    name CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
<家庭>
    <人 relID="P_1" name="爸爸"/>
    <人 relID="P_2" name="妈妈"/>
    <人 relID="P_3" parentID="P_1 P_2" name="儿子"/></家庭>
ログイン後にコピー
ログイン後にコピー

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

<!ATTLIST person
    婚姻状态 (single|married|porced|widowed) #IMPLIED><!ATTLIST person
    性别 (男|女) #REQUIRED>
ログイン後にコピー
ログイン後にコピー

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

实体定义:
- 实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
- 在DTD定义中,一条!ENTITY语句用于定义一个实体。
- 实体可分为两种类型:引用实体和参数实体。引用实体是被XML文档应用的,而参数实体是被DTD文件本身应用的。

①引用实体:

  • 引用实体主要在XML文档中被应用
    语法格式如下,引用实体的定义内容最好放在DTD文件的最后。

<!ENTITY 实体名称 "实体内容">
ログイン後にコピー

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

举例如下:

<!ENTITY copyright "I am a programmer">....
&copyright;
ログイン後にコピー
ログイン後にコピー

②参数实体:

参数实体被DTD文件自身使用
语法格式为:

<!ENTITY % 实体名称 "实体内容">
ログイン後にコピー
ログイン後にコピー

引用方式为:%实体名称

举例:

<!ENTITY % TAG_NAME "姓名|EMAIL|电话|地址"><!ELEMENT 个人信息 (%TAG_NAME;|生日)><!ELEMENT 客户信息 (%TAG_NAME;|公司名)>
ログイン後にコピー
ログイン後にコピー

3.DTD实际案例

学习DTD的目标在于:
(1)要求我们能够看得懂DTD文件,
(2)我们可以根据给出的DTD写出对应的XML文件

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

<!ENTITY AUTHOR "John Doe"><!ENTITY COMPANY "JD Power Tools, Inc."><!ENTITY EMAIL "jd@jd-tools.com"><!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)><!ATTLIST PRODUCTNAME CDATA #IMPLIEDCATEGORY (HandTool|Table|Shop-Professional) 
"HandTool"PARTNUM CDATA #IMPLIEDPLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)><!ATTLIST SPECIFICATIONSWEIGHT CDATA #IMPLIEDPOWER CDATA #IMPLIED><!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONSFINISH (Metal|Polished|Matte) "Matte" 
ADAPTER (Included|Optional|NotApplicable) "Included"CASE (HardShell|Soft|NotApplicable) "HardShell"><!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICEMSRP CDATA #IMPLIEDWHOLESALE CDATA #IMPLIEDSTREET CDATA #IMPLIEDSHIPPING CDATA #IMPLIED><!ELEMENT NOTES (#PCDATA)>
ログイン後にコピー

然后我们可以根据该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>
ログイン後にコピー
ログイン後にコピー

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

1.XML文件约束与DTD的简单介绍

我们编写文档来约束一个XML文档的书写规范,这称之为XML约束。

常用的约束技术有:

  • XML DTD

  • XML Schema

DTD的基本概念:

document type definition 文档类型定义

DTD文件一般和XML文件配合使用,主要是为了约束XML文件。

XML文件引入DTD文件,这样XML可以自定义标签,但又受到DTD文件的约束。比如上一节使用XML描述一个班级的信息,如果我们给每一个学生定义一个<面积>标签,语法上也是没有错误的,但是不符合语义,学生怎么能够用面积来描述呢?这时候我们就需要用到DTD文件来约束这个XML。

<?xml version="1.0" encoding="gb2312"?><class>
    <stu id="001">
        <name>杨过</name> 
        <sex>男</sex>
        <age>20</age>
        <面积>100</面积>
    </stu></class>
ログイン後にコピー
ログイン後にコピー

1.1 DTD约束快速入门案例

基本语法:

<!ELEMENT 元素名 类型>
ログイン後にコピー
ログイン後にコピー

我们还以班级为例,编写如下DTD文件,myClass.dtd:

<!ELEMENT 班级 (学生+)><!ELEMENT 学生 (名字,年龄,介绍)><!ELEMENT 名字 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 介绍 (#PCDATA)>
ログイン後にコピー
ログイン後にコピー

第一行表示根元素为班级,并且有学生这个子元素,子元素为1或者多个。
第二行表示学生的子元素为名字,年龄,介绍
名字下面没有子元素了,那么#PCDATA表示名字里面可以放任意文本。
年龄和介绍也是类似。

编写myClass.xml文件并引入DTD文件如下:

<?xml version="1.0" encoding="utf-8"?><!--引入dtd文件,约束这个xml--><!DOCTYPE 班级 SYSTEM "myClass.dtd"><班级>
    <学生>
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>   
    <学生>
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー

引入中写的:SYSTEM,表示当前的DTD文件是本地的
如果写的是PUBLIC,则表示引入的DTD文件是来自于网络的.

这时候引入的DTD文件是没有产生作用的,如果我们在学生元素中添加子元素<面积>,打开这个XML文件,浏览器依然不会报错。

<?xml version="1.0" encoding="utf-8"?><!--引入dtd文件,约束这个xml--><!DOCTYPE 班级 SYSTEM "myClass.dtd"><班级>
    <学生>
        <名字>周小星</名字>    
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
        <面积>100平米</面积>
    </学生>   
    <学生>
        <名字>林晓</名字> 
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー

我们需要编程校验XML文档的正确性

IE5以上的浏览器内置了XML解析工具:Microsoft.XMLDOM,开发人员可以编写JavaScript代码,利用这个解析工具装载XML文件,并对XML文件进行DTD验证。

我们编写myXmlTools.html来对这个XML进行校验,如下:

<html>
    <head>
    <!--自己编写一个简单的解析工具,去解析XML DTD是否配套-->     
    <script language="javascript">
        // 创建xml文档解析器对象
        var xmldoc = new ActiveXObject("Microsoft.XMLDOM");        // 开启xml校验
        xmldoc.validateOnParse = "true";        // 装载xml文档,即指定校验哪个XML文件
        xmldoc.load("myClass.xml");
        document.writeln("错误信息:"+xmldoc.parseError.reason+"<br>");
        document.writeln("错误行号:"+xmldoc.parseError.line);    </script>

    </head>
    <body>

    </body></html>
ログイン後にコピー
ログイン後にコピー

用IE浏览器打开这个html文件,可以看到运行结果:

XML - XML ドキュメント制約の DTD の詳細な説明

可以看到第9行正是我们添加的<面积>这一行。

2.DTD细节

2.1 DTD文档的声明及引用

1.内部DTD文档

<!DOCTYPE 根元素 [定义内容]>
ログイン後にコピー
ログイン後にコピー

2.外部DTD文档

引入外部的DTD文档分为两种:

(1)当引用的DTD文件是本地文件的时候,用SYSTEM标识,并写上”DTD的文件路径”,如下:

<!DOCTYPE 根元素 SYSTEM "DTD文件路径">
ログイン後にコピー
ログイン後にコピー

(2)如果引用的DTD文件是一个公共的文件时,采用PUBLIC标识,如下方式:

<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件的URL">
ログイン後にコピー
ログイン後にコピー

比如下例:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
ログイン後にコピー
ログイン後にコピー

2.2 DTD基本语法:

<!ELEMENT NAME CONTENT>
ログイン後にコピー
ログイン後にコピー

其中:
- ELEMENT是关键字,是不能修改的
- NAME表示元素名称
- CONTENT是元素类型,必须要大写!CONTENT的内容有三种写法:

(1)EMPTY——表示该元素不能包含子元素和文本,但可以有属性。
(2)ANY——表示该元素可以包含任何在该DTD中定义的元素内容
(3)#PCDATA——可以包含任何字符数据,但是不能在其中包含任何子元素

2.3 DTD元素的组合类型:

DTD中这样规定:

<!ELEMENT 家庭(人+,家电*)>
ログイン後にコピー

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

XML这样写:

<家庭>
    <人 名字="张晓明" 性别="男" 年龄="25"/>
    <人 名字="李小钢" 性别="男" 年龄="36" 爱好="作个教育家和伟人"/>
    <家电 名称="彩电" 数量="3"/></家庭>
ログイン後にコピー
ログイン後にコピー

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

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

2.4 属性定义

DTD中属性的定义是这样的:

<!ATTLIST 元素名称
    属性名称 类型 属性特点
    属性名称 类型 属性特点......  >
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

其中,属性的类型有下面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</年龄>
        <介绍>是一个好学生</介绍>
    </学生>   </班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

<!ELEMENT 班级 (学生+)><!ELEMENT 学生 (名字,年龄,介绍)><!ATTLIST 学生
    地址 CDATA #REQUIRED><!ELEMENT 名字 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 介绍 (#PCDATA)>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

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

<!ATTLIST 木偶
    姓名 CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
<木偶 姓名="匹诺曹"/><木偶 姓名="PiNuocao"/><木偶 姓名="123"/>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

<!ELEMENT 公司职员 ANY><!ATTLIST 公司职员
    编号 ID #REQUIRED
    姓名 CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
<公司职员 编号="Z001" 姓名="张三"/><公司职员 编号="Z002" 姓名="李思"/>
ログイン後にコピー
ログイン後にコピー

(3)属性类型-IDREF/IDREFS
- IDREF属性的值指向文档中其它地方声明的ID类型的值
- IDREFS同IDREF,但是可以具有由空格分开的多个引用。

<!ELEMENT 家庭(人+)><!ELEMENT 人 EMPTY><!ATTLIST 人    relID ID #REQUIRED
    paraentID IDREFS #IMPLIED
    name CDATA #REQUIRED>
ログイン後にコピー
ログイン後にコピー
<家庭>
    <人 relID="P_1" name="爸爸"/>
    <人 relID="P_2" name="妈妈"/>
    <人 relID="P_3" parentID="P_1 P_2" name="儿子"/></家庭>
ログイン後にコピー
ログイン後にコピー

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

<!ATTLIST person
    婚姻状态 (single|married|porced|widowed) #IMPLIED><!ATTLIST person
    性别 (男|女) #REQUIRED>
ログイン後にコピー
ログイン後にコピー

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

实体定义:
- 实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
- 在DTD定义中,一条!ENTITY语句用于定义一个实体。
- 实体可分为两种类型:引用实体和参数实体。引用实体是被XML文档应用的,而参数实体是被DTD文件本身应用的。

①引用实体:

  • 引用实体主要在XML文档中被应用
    语法格式如下,引用实体的定义内容最好放在DTD文件的最后。

<!ENTITY 实体名称 "实体内容">
ログイン後にコピー

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

举例如下:

<!ENTITY copyright "I am a programmer">....
&copyright;
ログイン後にコピー
ログイン後にコピー

②参数实体:

参数实体被DTD文件自身使用
语法格式为:

<!ENTITY % 实体名称 "实体内容">
ログイン後にコピー
ログイン後にコピー

引用方式为:%实体名称

举例:

<!ENTITY % TAG_NAME "姓名|EMAIL|电话|地址"><!ELEMENT 个人信息 (%TAG_NAME;|生日)><!ELEMENT 客户信息 (%TAG_NAME;|公司名)>
ログイン後にコピー
ログイン後にコピー

3.DTD实际案例

学习DTD的目标在于:
(1)要求我们能够看得懂DTD文件,
(2)我们可以根据给出的DTD写出对应的XML文件

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

<!ENTITY AUTHOR "John Doe"><!ENTITY COMPANY "JD Power Tools, Inc."><!ENTITY EMAIL "jd@jd-tools.com">
<!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCTNAME CDATA #IMPLIEDCATEGORY (HandTool|Table|Shop-Professional) "HandTool"PARTNUM CDATA 
#IMPLIEDPLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONSWEIGHT CDATA #IMPLIEDPOWER CDATA #IMPLIED>
<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONSFINISH (Metal|Polished|Matte) "Matte" 
ADAPTER (Included|Optional|NotApplicable) "Included"CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICEMSRP CDATA #IMPLIEDWHOLESALE CDATA #IMPLIEDSTREET CDATA #IMPLIEDSHIPPING CDATA #IMPLIED>
<!ELEMENT NOTES (#PCDATA)>
ログイン後にコピー

然后我们可以根据该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>
ログイン後にコピー
ログイン後にコピー

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

 以上就是XML—XML文件约束之DTD详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート