活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

DTD文档类型定义详解如何规范XML文档结构确保数据交换一致性与有效性

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-29 13:50:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

XML(可扩展标记语言)作为一种通用的数据交换格式,已被广泛应用于各个领域,从Web服务到企业应用集成,从配置文件到文档存储。然而,要确保XML文档在不同系统间的有效交换和处理,必须有一种机制来定义和验证文档的结构。DTD(Document Type Definition,文档类型定义)正是这样一种机制,它为XML文档提供了结构化的规范,确保数据交换的一致性与有效性。

DTD基础概念

什么是DTD

DTD(Document Type Definition,文档类型定义)是一套用于定义XML文档结构的规则集合。它规定了XML文档中可以包含哪些元素、元素之间的关系、元素可以具有哪些属性以及它们的默认值等。DTD可以看作是XML文档的”蓝图”或”模板”,它定义了文档的合法构建块。

为什么需要DTD

在数据交换过程中,如果没有统一的结构规范,不同的系统可能会生成结构各异的XML文档,导致数据解析和处理困难。DTD的出现解决了这个问题,它通过以下方式确保XML文档的质量:

1. 结构一致性:确保所有XML文档遵循相同的结构规则。
2. 数据有效性:验证文档中的数据是否符合预定义的规则。
3. 互操作性:使不同系统能够理解和处理相同结构的XML文档。
4. 文档化:为XML文档提供自描述的元数据。

DTD的语法和结构

DTD可以使用内部声明或外部引用的方式包含在XML文档中。内部DTD直接写在XML文档中,而外部DTD则保存在单独的文件中,通过URL引用。

内部DTD示例
  1. <!DOCTYPE note [
  2.   <!ELEMENT note (to,from,heading,body)>
  3.   <!ELEMENT to (#PCDATA)>
  4.   <!ELEMENT from (#PCDATA)>
  5.   <!ELEMENT heading (#PCDATA)>
  6.   <!ELEMENT body (#PCDATA)>
  7. ]>
  8. <note>
  9.   <to>Tove</to>
  10.   <from>Jani</from>
  11.   <heading>Reminder</heading>
  12.   <body>Don't forget me this weekend!</body>
  13. </note>
复制代码

外部DTD示例
  1. <!-- XML文档 -->
  2. <!DOCTYPE note SYSTEM "note.dtd">
  3. <note>
  4.   <to>Tove</to>
  5.   <from>Jani</from>
  6.   <heading>Reminder</heading>
  7.   <body>Don't forget me this weekend!</body>
  8. </note>
  9. <!-- note.dtd文件 -->
  10. <!ELEMENT note (to,from,heading,body)>
  11. <!ELEMENT to (#PCDATA)>
  12. <!ELEMENT from (#PCDATA)>
  13. <!ELEMENT heading (#PCDATA)>
  14. <!ELEMENT body (#PCDATA)>
复制代码

元素声明

元素声明是DTD中最基本的部分,它定义了XML文档中可以包含的元素及其内容模型。元素声明的基本语法是:
  1. <!ELEMENT element-name content-model>
复制代码

内容模型可以是以下几种类型:

1. EMPTY:元素不能包含任何内容。<!ELEMENT br EMPTY>
2. (#PCDATA):元素只能包含文本内容(Parsed Character Data)。<!ELEMENT title (#PCDATA)>
3. 子元素:元素必须包含指定的子元素,可以指定顺序和出现次数。<!ELEMENT note (to,from,heading,body)>
4. 混合内容:元素可以包含文本和子元素的混合。<!ELEMENT description (#PCDATA|emph)*>
5. ANY:元素可以包含任何内容。<!ELEMENT misc ANY>

EMPTY:元素不能包含任何内容。
  1. <!ELEMENT br EMPTY>
复制代码

(#PCDATA):元素只能包含文本内容(Parsed Character Data)。
  1. <!ELEMENT title (#PCDATA)>
复制代码

子元素:元素必须包含指定的子元素,可以指定顺序和出现次数。
  1. <!ELEMENT note (to,from,heading,body)>
复制代码

混合内容:元素可以包含文本和子元素的混合。
  1. <!ELEMENT description (#PCDATA|emph)*>
复制代码

ANY:元素可以包含任何内容。
  1. <!ELEMENT misc ANY>
复制代码

元素出现次数的控制符号:

• *:零次或多次
• +:一次或多次
• ?:零次或一次
• 无符号:恰好一次

示例:
  1. <!ELEMENT book (title, author+, publisher*, price?, chapter*)>
复制代码

这个声明表示book元素必须包含一个title,一个或多个author,零个或多个publisher,零个或一个price,以及零个或多个chapter。

属性声明

属性声明定义了元素可以具有的属性及其类型和默认值。属性声明的基本语法是:
  1. <!ATTLIST element-name
  2.   attribute-name attribute-type default-value
  3. >
复制代码

属性类型包括:

1. CDATA:字符数据
2. ID:唯一标识符
3. IDREF/IDREFS:引用其他元素的ID
4. NMTOKEN/NMTOKENS:名称标记
5. 枚举:预定义的值列表

默认值类型包括:

1. #REQUIRED:属性必须出现
2. #IMPLIED:属性可选
3. #FIXED value:属性有固定值
4. default:属性的默认值

示例:
  1. <!ATTLIST book
  2.   id ID #REQUIRED
  3.   lang NMTOKEN "en"
  4.   available (true|false) "true"
  5. >
复制代码

实体声明

实体声明定义了可在XML文档中引用的变量或宏。实体声明的基本语法是:
  1. <!ENTITY entity-name "entity-value">
复制代码

实体可以是:

1. 内部实体:在DTD内部定义的简单文本替换。<!ENTITY copyright "Copyright © 2023 Example Corp.">
2. 外部实体:引用外部文件的内容。<!ENTITY footer SYSTEM "footer.xml">
3. 参数实体:只能在DTD内部使用的实体,以%开头。<!ENTITY % common-elements "title | author | publisher">

内部实体:在DTD内部定义的简单文本替换。
  1. <!ENTITY copyright "Copyright © 2023 Example Corp.">
复制代码

外部实体:引用外部文件的内容。
  1. <!ENTITY footer SYSTEM "footer.xml">
复制代码

参数实体:只能在DTD内部使用的实体,以%开头。
  1. <!ENTITY % common-elements "title | author | publisher">
复制代码

DTD如何规范XML文档结构

DTD通过以下方式规范XML文档的结构:

1. 定义元素层次结构

DTD明确规定了XML文档中元素的嵌套关系和顺序。例如:
  1. <!ELEMENT book (title, author+, publisher?, chapter+)>
  2. <!ELEMENT chapter (section+)>
  3. <!ELEMENT section (title, para+)>
复制代码

这个DTD定义了book元素的结构:必须包含一个title,一个或多个author,可选的publisher,以及一个或多个chapter。每个chapter必须包含一个或多个section,而每个section必须包含一个title和一个或多个para。

这种层次结构确保了XML文档的组织方式符合预期,避免了混乱或不合理的嵌套。

2. 限制元素内容

DTD可以精确指定元素可以包含的内容类型,如纯文本、其他元素或混合内容。例如:
  1. <!ELEMENT title (#PCDATA)>
  2. <!ELEMENT para (#PCDATA|emph|strong)*>
  3. <!EMPTY image EMPTY>
复制代码

这些声明确保:

• title元素只能包含文本内容
• para元素可以包含文本、emph元素和strong元素的混合内容
• image元素必须是空元素,不能包含任何内容

3. 定义属性约束

DTD通过属性声明为元素添加额外的约束和元数据。例如:
  1. <!ATTLIST product
  2.   id ID #REQUIRED
  3.   category CDATA #REQUIRED
  4.   price NMTOKEN #REQUIRED
  5.   currency (USD|EUR|GBP) "USD"
  6.   inStock (true|false) "true"
  7. >
复制代码

这个声明确保:

• 每个product元素必须有一个唯一的id属性
• category和price属性是必需的
• currency属性只能是USD、EUR或GBP,默认为USD
• inStock属性只能是true或false,默认为true

4. 提供数据重用机制

通过实体声明,DTD允许在多个位置重用相同的内容或结构。例如:
  1. <!ENTITY % common-attrs "
  2.   id ID #IMPLIED
  3.   class CDATA #IMPLIED
  4.   style CDATA #IMPLIED
  5. ">
  6. <!ATTLIST p %common-attrs;>
  7. <!ATTLIST div %common-attrs;>
  8. <!ATTLIST span %common-attrs;>
复制代码

这个参数实体common-attrs定义了一组通用属性,然后可以应用到多个元素中,避免了重复声明。

DTD在确保数据交换一致性方面的作用

DTD在确保数据交换一致性方面发挥着关键作用,主要体现在以下几个方面:

1. 统一数据格式

DTD为所有参与数据交换的各方提供了统一的数据格式规范。例如,在电子商务系统中,订单信息的DTD可能如下:
  1. <!ELEMENT order (order-header, order-items)>
  2. <!ELEMENT order-header (order-id, customer-id, order-date, shipping-address)>
  3. <!ELEMENT order-items (item+)>
  4. <!ELEMENT item (product-id, quantity, unit-price)>
  5. <!ELEMENT order-id (#PCDATA)>
  6. <!ELEMENT customer-id (#PCDATA)>
  7. <!ELEMENT order-date (#PCDATA)>
  8. <!ELEMENT shipping-address (street, city, state, zip, country)>
  9. <!ELEMENT street (#PCDATA)>
  10. <!ELEMENT city (#PCDATA)>
  11. <!ELEMENT state (#PCDATA)>
  12. <!ELEMENT zip (#PCDATA)>
  13. <!ELEMENT country (#PCDATA)>
  14. <!ELEMENT product-id (#PCDATA)>
  15. <!ELEMENT quantity (#PCDATA)>
  16. <!ELEMENT unit-price (#PCDATA)>
复制代码

这个DTD确保了所有订单XML文档都遵循相同的结构,包含相同的元素和属性,从而使得不同系统(如订单处理系统、库存管理系统、财务系统)能够一致地理解和处理订单数据。

2. 确保数据完整性

通过强制要求某些元素或属性的存在,DTD确保了关键数据不会缺失。例如:
  1. <!ELEMENT employee (name, department, position)>
  2. <!ATTLIST employee
  3.   emp-id ID #REQUIRED
  4.   status (active|inactive|terminated) "active"
  5. >
复制代码

这个DTD确保每个员工记录都必须包含name、department和position元素,以及一个必需的emp-id属性。这样可以防止不完整的员工数据进入系统。

3. 标准化数据表示

DTD可以标准化数据的表示方式,避免歧义。例如:
  1. <!ELEMENT date (#PCDATA)>
  2. <!ATTLIST date
  3.   format (mm/dd/yyyy|dd/mm/yyyy|yyyy-mm-dd) "yyyy-mm-dd"
  4. >
复制代码

这个DTD确保日期数据总是以指定的格式之一表示,默认为ISO标准的yyyy-mm-dd格式,避免了不同地区日期格式的混淆。

4. 支持数据验证

DTD提供了一种机制来验证XML文档是否符合预定义的结构规则。大多数XML解析器都可以根据DTD验证XML文档的有效性。例如,如果XML文档包含DTD中未声明的元素,或者元素顺序不正确,解析器将报告错误。

这种验证可以在数据交换的早期阶段发现问题,防止无效数据进入系统,减少后续处理的错误和异常。

DTD在确保数据有效性方面的作用

除了确保数据结构的一致性外,DTD还在确保数据有效性方面发挥重要作用:

1. 类型约束

虽然DTD的数据类型系统相对简单,但它提供了一些基本的数据类型约束:
  1. <!ATTLIST product
  2.   id ID #REQUIRED
  3.   price NMTOKEN #REQUIRED
  4.   weight NMTOKEN #IMPLIED
  5.   available (true|false) "true"
  6. >
复制代码

这个DTD确保:

• id属性必须是唯一的标识符
• price和weight属性必须是有效的名称标记(不能包含空格等特殊字符)
• available属性只能是”true”或”false”

2. 值约束

DTD可以通过枚举方式限制属性值的范围:
  1. <!ATTLIST book
  2.   category (fiction|non-fiction|biography|science|technology) #REQUIRED
  3.   language (en|fr|de|es|ja|zh) "en"
  4.   edition (1|2|3|4|5) "1"
  5. >
复制代码

这个DTD确保:

• category属性必须是预定义的类别之一
• language属性只能是指定的语言代码之一,默认为”en”
• edition属性只能是1到5之间的数字,默认为1

3. 唯一性约束

通过ID类型属性,DTD可以确保某些值的唯一性:
  1. <!ELEMENT employees (employee+)>
  2. <!ELEMENT employee (name, department)>
  3. <!ATTLIST employee
  4.   emp-id ID #REQUIRED
  5.   manager-id IDREF #IMPLIED
  6. >
复制代码

这个DTD确保:

• 每个employee元素都有一个唯一的emp-id属性
• manager-id属性必须引用另一个有效的emp-id值

4. 引用完整性

通过IDREF和IDREFS类型,DTD可以维护元素之间的引用关系:
  1. <!ELEMENT library (book+, patron+, loan+)>
  2. <!ELEMENT book (title, author)>
  3. <!ATTLIST book
  4.   book-id ID #REQUIRED
  5. >
  6. <!ELEMENT patron (name, address)>
  7. <!ATTLIST patron
  8.   patron-id ID #REQUIRED
  9. >
  10. <!ELEMENT loan EMPTY>
  11. <!ATTLIST loan
  12.   book-id IDREF #REQUIRED
  13.   patron-id IDREF #REQUIRED
  14.   due-date CDATA #REQUIRED
  15. >
复制代码

这个DTD确保:

• loan元素的book-id和patron-id属性必须分别引用有效的book-id和patron-id值
• 这防止了引用不存在的书籍或借阅者的情况

DTD的实际应用案例

案例1:电子商务产品目录

假设一个电子商务平台需要定义产品目录的XML结构,可以使用以下DTD:
  1. <!ELEMENT catalog (category+)>
  2. <!ELEMENT category (name, description?, product+)>
  3. <!ATTLIST category
  4.   id ID #REQUIRED
  5.   parent-id IDREF #IMPLIED
  6. >
  7. <!ELEMENT product (name, description, price, availability)>
  8. <!ATTLIST product
  9.   id ID #REQUIRED
  10.   sku NMTOKEN #REQUIRED
  11.   category-id IDREF #REQUIRED
  12. >
  13. <!ELEMENT name (#PCDATA)>
  14. <!ELEMENT description (#PCDATA)>
  15. <!ELEMENT price (#PCDATA)>
  16. <!ATTLIST price
  17.   currency (USD|EUR|GBP|JPY) "USD"
  18. >
  19. <!ELEMENT availability (in-stock, shipping-info?)>
  20. <!ELEMENT in-stock (#PCDATA)>
  21. <!ELEMENT shipping-info (#PCDATA)>
复制代码

这个DTD定义了一个分层次的产品目录结构,其中:

• 目录包含多个类别
• 每个类别可以有父类别,形成层次结构
• 产品属于特定类别
• 价格有货币类型属性
• 可用性信息包括库存信息和可选的运输信息

使用这个DTD的XML文档示例:
  1. <!DOCTYPE catalog SYSTEM "catalog.dtd">
  2. <catalog>
  3.   <category id="cat1" parent-id="cat0">
  4.     <name>Electronics</name>
  5.     <description>Electronic devices and gadgets</description>
  6.     <product id="prod1" sku="EL001" category-id="cat1">
  7.       <name>Smartphone</name>
  8.       <description>Latest model with advanced features</description>
  9.       <price currency="USD">699.99</price>
  10.       <availability>
  11.         <in-stock>yes</in-stock>
  12.         <shipping-info>Free shipping</shipping-info>
  13.       </availability>
  14.     </product>
  15.   </category>
  16. </catalog>
复制代码

案例2:医疗记录系统

在医疗记录系统中,数据的一致性和有效性至关重要。以下是一个简化的医疗记录DTD:
  1. <!ELEMENT medical-records (patient+)>
  2. <!ELEMENT patient (personal-info, medical-history, visits+)>
  3. <!ATTLIST patient
  4.   patient-id ID #REQUIRED
  5. >
  6. <!ELEMENT personal-info (name, dob, gender, contact-info)>
  7. <!ELEMENT name (first, last, middle?)>
  8. <!ELEMENT first (#PCDATA)>
  9. <!ELEMENT last (#PCDATA)>
  10. <!ELEMENT middle (#PCDATA)>
  11. <!ELEMENT dob (#PCDATA)>
  12. <!ATTLIST dob
  13.   format CDATA "yyyy-mm-dd"
  14. >
  15. <!ELEMENT gender (male|female|other)>
  16. <!ELEMENT contact-info (phone, email, address)>
  17. <!ELEMENT phone (#PCDATA)>
  18. <!ELEMENT email (#PCDATA)>
  19. <!ELEMENT address (street, city, state, zip, country)>
  20. <!ELEMENT street (#PCDATA)>
  21. <!ELEMENT city (#PCDATA)>
  22. <!ELEMENT state (#PCDATA)>
  23. <!ELEMENT zip (#PCDATA)>
  24. <!ELEMENT country (#PCDATA)>
  25. <!ELEMENT medical-history (condition+, medication+, allergy?)>
  26. <!ELEMENT condition (name, diagnosed-date, status)>
  27. <!ATTLIST condition
  28.   id ID #REQUIRED
  29. >
  30. <!ELEMENT diagnosed-date (#PCDATA)>
  31. <!ELEMENT status (active|resolved|chronic)>
  32. <!ELEMENT medication (name, dosage, start-date, end-date?)>
  33. <!ATTLIST medication
  34.   id ID #REQUIRED
  35. >
  36. <!ELEMENT dosage (#PCDATA)>
  37. <!ELEMENT start-date (#PCDATA)>
  38. <!ELEMENT end-date (#PCDATA)>
  39. <!ELEMENT allergy (substance, reaction, severity)>
  40. <!ATTLIST allergy
  41.   id ID #REQUIRED
  42. >
  43. <!ELEMENT substance (#PCDATA)>
  44. <!ELEMENT reaction (#PCDATA)>
  45. <!ELEMENT severity (mild|moderate|severe|life-threatening)>
  46. <!ELEMENT visits (visit+)>
  47. <!ELEMENT visit (date, reason, diagnosis, treatment, physician)>
  48. <!ATTLIST visit
  49.   id ID #REQUIRED
  50. >
  51. <!ELEMENT date (#PCDATA)>
  52. <!ELEMENT reason (#PCDATA)>
  53. <!ELEMENT diagnosis (#PCDATA)>
  54. <!ELEMENT treatment (#PCDATA)>
  55. <!ELEMENT physician (#PCDATA)>
复制代码

这个DTD定义了一个结构化的医疗记录系统,包括:

• 患者个人信息
• 医疗历史(疾病、药物、过敏)
• 就诊记录

使用这个DTD的XML文档示例:
  1. <!DOCTYPE medical-records SYSTEM "medical-records.dtd">
  2. <medical-records>
  3.   <patient patient-id="p12345">
  4.     <personal-info>
  5.       <name>
  6.         <first>John</first>
  7.         <last>Doe</last>
  8.       </name>
  9.       <dob format="yyyy-mm-dd">1980-05-15</dob>
  10.       <gender>male</gender>
  11.       <contact-info>
  12.         <phone>555-123-4567</phone>
  13.         <email>john.doe@example.com</email>
  14.         <address>
  15.           <street>123 Main St</street>
  16.           <city>Anytown</city>
  17.           <state>CA</state>
  18.           <zip>12345</zip>
  19.           <country>USA</country>
  20.         </address>
  21.       </contact-info>
  22.     </personal-info>
  23.     <medical-history>
  24.       <condition id="c1">
  25.         <name>Hypertension</name>
  26.         <diagnosed-date>2018-03-10</diagnosed-date>
  27.         <status>active</status>
  28.       </condition>
  29.       <medication id="m1">
  30.         <name>Lisinopril</name>
  31.         <dosage>10mg daily</dosage>
  32.         <start-date>2018-03-15</start-date>
  33.       </medication>
  34.       <allergy id="a1">
  35.         <substance>Penicillin</substance>
  36.         <reaction>Rash</reaction>
  37.         <severity>mild</severity>
  38.       </allergy>
  39.     </medical-history>
  40.     <visits>
  41.       <visit id="v1">
  42.         <date>2023-05-01</date>
  43.         <reason>Regular checkup</reason>
  44.         <diagnosis>Blood pressure under control</diagnosis>
  45.         <treatment>Continue current medication</treatment>
  46.         <physician>Dr. Smith</physician>
  47.       </visit>
  48.     </visits>
  49.   </patient>
  50. </medical-records>
复制代码

案例3:配置管理系统

在软件系统中,配置文件通常使用XML格式。以下是一个应用程序配置的DTD:
  1. <!ELEMENT config (database, logging, security, features)>
  2. <!ELEMENT database (host, port, name, user, password, pool-size)>
  3. <!ELEMENT host (#PCDATA)>
  4. <!ELEMENT port (#PCDATA)>
  5. <!ELEMENT name (#PCDATA)>
  6. <!ELEMENT user (#PCDATA)>
  7. <!ELEMENT password (#PCDATA)>
  8. <!ELEMENT pool-size (#PCDATA)>
  9. <!ELEMENT logging (level, file, max-size, backup-index)>
  10. <!ATTLIST logging
  11.   enabled (true|false) "true"
  12. >
  13. <!ELEMENT level (DEBUG|INFO|WARN|ERROR)>
  14. <!ELEMENT file (#PCDATA)>
  15. <!ELEMENT max-size (#PCDATA)>
  16. <!ELEMENT backup-index (#PCDATA)>
  17. <!ELEMENT security (auth-method, session-timeout, ssl)>
  18. <!ELEMENT auth-method (BASIC|FORM|TOKEN)>
  19. <!ELEMENT session-timeout (#PCDATA)>
  20. <!ELEMENT ssl EMPTY>
  21. <!ATTLIST ssl
  22.   enabled (true|false) "false"
  23.   keystore CDATA #IMPLIED
  24.   password CDATA #IMPLIED
  25. >
  26. <!ELEMENT features (feature+)>
  27. <!ELEMENT feature EMPTY>
  28. <!ATTLIST feature
  29.   name CDATA #REQUIRED
  30.   enabled (true|false) "true"
  31.   version CDATA #IMPLIED
  32. >
复制代码

这个DTD定义了一个应用程序配置的结构,包括:

• 数据库连接设置
• 日志配置
• 安全设置
• 功能开关

使用这个DTD的XML文档示例:
  1. <!DOCTYPE config SYSTEM "config.dtd">
  2. <config>
  3.   <database>
  4.     <host>localhost</host>
  5.     <port>5432</port>
  6.     <name>myapp_db</name>
  7.     <user>admin</user>
  8.     <password>secret</password>
  9.     <pool-size>10</pool-size>
  10.   </database>
  11.   <logging enabled="true">
  12.     <level>INFO</level>
  13.     <file>/var/log/myapp.log</file>
  14.     <max-size>10MB</max-size>
  15.     <backup-index>5</backup-index>
  16.   </logging>
  17.   <security>
  18.     <auth-method>FORM</auth-method>
  19.     <session-timeout>30</session-timeout>
  20.     <ssl enabled="false"/>
  21.   </security>
  22.   <features>
  23.     <feature name="user-profile" enabled="true" version="1.2"/>
  24.     <feature name="reporting" enabled="false"/>
  25.     <feature name="notifications" enabled="true"/>
  26.   </features>
  27. </config>
复制代码

DTD的优缺点

DTD的优点

1. 简单性:DTD语法相对简单,易于学习和使用。
2. 广泛支持:DTD是XML规范的一部分,几乎所有的XML解析器都支持DTD验证。
3. 历史悠久:DTD是XML最早的验证机制,有丰富的文档和工具支持。
4. 性能:DTD验证通常比其他模式语言(如XML Schema)更快。
5. 实体支持:DTD提供了强大的实体机制,支持文本替换和外部内容引用。

DTD的缺点

1. 有限的数据类型:DTD只支持有限的数据类型,没有对数字、日期等特定类型的支持。
2. 非XML语法:DTD使用自己的语法,而不是XML语法,这使得处理DTD需要特殊的解析器。
3. 命名空间支持有限:DTD对XML命名空间的支持不够完善。
4. 缺乏扩展性:DTD难以扩展和重用,模块化能力有限。
5. 文档和验证混合:DTD既用于文档验证,也用于实体声明,职责不够明确。
6. 无法定义复杂约束:DTD难以表达复杂的业务规则和约束。

DTD与其他XML模式技术的比较

DTD与XML Schema的比较

XML Schema(XSD)是W3C推荐的另一种XML文档定义语言,它提供了比DTD更强大的功能:

示例比较:

DTD版本:
  1. <!ELEMENT book (title, author+, publisher?, price)>
  2. <!ELEMENT title (#PCDATA)>
  3. <!ELEMENT author (#PCDATA)>
  4. <!ELEMENT publisher (#PCDATA)>
  5. <!ELEMENT price (#PCDATA)>
  6. <!ATTLIST price
  7.   currency (USD|EUR|GBP) "USD"
  8. >
复制代码

XML Schema版本:
  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  2.   <xs:element name="book">
  3.     <xs:complexType>
  4.       <xs:sequence>
  5.         <xs:element name="title" type="xs:string"/>
  6.         <xs:element name="author" type="xs:string" maxOccurs="unbounded"/>
  7.         <xs:element name="publisher" type="xs:string" minOccurs="0"/>
  8.         <xs:element name="price">
  9.           <xs:complexType>
  10.             <xs:simpleContent>
  11.               <xs:extension base="xs:decimal">
  12.                 <xs:attribute name="currency" type="currencyType" default="USD"/>
  13.               </xs:extension>
  14.             </xs:simpleContent>
  15.           </xs:complexType>
  16.         </xs:element>
  17.       </xs:sequence>
  18.     </xs:complexType>
  19.   </xs:element>
  20.   
  21.   <xs:simpleType name="currencyType">
  22.     <xs:restriction base="xs:string">
  23.       <xs:enumeration value="USD"/>
  24.       <xs:enumeration value="EUR"/>
  25.       <xs:enumeration value="GBP"/>
  26.     </xs:restriction>
  27.   </xs:simpleType>
  28. </xs:schema>
复制代码

DTD与RELAX NG的比较

RELAX NG是另一种XML模式语言,它提供了更简洁和强大的语法:

示例比较:

DTD版本:
  1. <!ELEMENT book (title, author+, publisher?, price)>
  2. <!ELEMENT title (#PCDATA)>
  3. <!ELEMENT author (#PCDATA)>
  4. <!ELEMENT publisher (#PCDATA)>
  5. <!ELEMENT price (#PCDATA)>
  6. <!ATTLIST price
  7.   currency (USD|EUR|GBP) "USD"
  8. >
复制代码

RELAX NG版本:
  1. <grammar xmlns="http://relaxng.org/ns/structure/1.0">
  2.   <start>
  3.     <element name="book">
  4.       <element name="title"><text/></element>
  5.       <oneOrMore>
  6.         <element name="author"><text/></element>
  7.       </oneOrMore>
  8.       <optional>
  9.         <element name="publisher"><text/></element>
  10.       </optional>
  11.       <element name="price">
  12.         <attribute name="currency">
  13.           <choice>
  14.             <value>USD</value>
  15.             <value>EUR</value>
  16.             <value>GBP</value>
  17.           </choice>
  18.         </attribute>
  19.         <text/>
  20.       </element>
  21.     </element>
  22.   </start>
  23. </grammar>
复制代码

结论:DTD在现代数据交换中的地位和未来

尽管DTD有一些局限性,特别是在数据类型和命名空间支持方面,但它仍然是XML技术生态系统中的重要组成部分。在许多现有系统和应用中,DTD继续发挥着作用,特别是在以下场景:

1. 遗留系统:许多旧的XML应用程序使用DTD,维护这些系统需要继续使用DTD。
2. 简单文档:对于结构简单的XML文档,DTD提供了足够的验证能力,且比其他模式语言更轻量。
3. 实体管理:DTD的实体机制在某些场景下仍然有用,如文档模板和文本替换。
4. 性能敏感应用:DTD验证通常比XML Schema更快,适合性能敏感的应用。

然而,对于新的XML项目,特别是需要复杂数据类型、命名空间支持或高级约束的场景,XML Schema或RELAX NG可能是更好的选择。

随着JSON等更轻量级数据交换格式的兴起,XML及其模式语言(包括DTD)的使用可能在某些领域减少。但在企业应用集成、文档标记和需要严格结构验证的场景中,XML和DTD仍将继续发挥重要作用。

总之,DTD作为XML文档结构定义的先驱,为数据交换的一致性和有效性提供了基础保障。了解和掌握DTD对于处理遗留系统和某些特定场景的XML应用仍然很有价值,同时也为学习更现代的XML模式技术奠定了基础。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则