乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • XML 基础语法

    • XML 概述
    • XML 文档结构
    • XML 元素
    • XML 属性
    • XML 语法规则
    • XML 命名空间
    • XML 注释与处理指令
  • DTD 与文档验证

    • DTD 概述
    • DTD 元素声明
    • DTD 属性声明
    • DTD 实体声明
    • DTD 元素与属性对比
    • DTD 完整示例
  • XML Schema 定义

    • XML Schema 概述
    • XSD 简单类型
    • XSD 复杂类型
    • XSD 命名空间与引用
  • XPath 节点定位

    • XPath 概述
    • XPath 路径表达式
    • XPath 谓词与函数
  • XSLT 转换

    • XSLT 概述
    • XSLT 模板与匹配
    • XSLT 控制结构
    • XSLT 输出控制
  • XML 解析技术

    • XML 解析概述
    • DOM 解析
    • SAX 解析
    • StAX 解析
    • XML 与 Java — JAXP
  • XML 在 Java 中的应用

    • Spring XML 配置
    • MyBatis XML 映射
    • pom.xml 与 Maven
    • web.xml 配置详解
  • 现代数据格式对比

    • XML 与 JSON 对比
    • XML 与 YAML 对比
  • XML 显示与浏览器集成

    • XML 在浏览器中的显示
    • XMLHttpRequest 与 AJAX
    • 服务器端 XML 处理
  • XML 进阶查询与链接

    • XQuery 查询语言
    • XLink 超链接
    • XML 验证工具使用
  • XML Web 服务(选读)

    • XML Web 服务概述
    • SOAP 协议详解
    • WSDL 服务描述
    • RSS 内容聚合
    • RDF 资源描述框架

DTD 属性声明

本章定位 :掌握 DTD 中 <!ATTLIST> 声明的完整语法——属性类型(CDATA/ID/IDREF/NMTOKEN/枚举)、默认值修饰符(#REQUIRED/#IMPLIED/#FIXED)以及 ID/IDREF 的跨元素关联机制。

定义与作用

DTD 中的 <!ATTLIST> 声明用于定义元素可以携带哪些属性、每个属性的类型、是否必填、以及默认值。

DTD 属性声明的两个核心功能:

  1. 约束属性的值类型 :如 ID(全局唯一标识)、枚举(限定可选值)、IDREF(引用其他元素的 ID)
  2. 控制属性的存在性 :#REQUIRED(必填)、#IMPLIED(可选)、#FIXED(固定值)

核心原理:ID/IDREF 关联机制

图解释 :ID/IDREF 机制在 XML 文档内部建立类似"外键"的关系。enrollment 通过 student_ref 和 course_ref 属性引用 student 和 course 的 ID——验证器会检查引用的 ID 是否存在。

语法/结构要点

属性类型一览

类型说明示例
CDATA任意字符串(最常用)name CDATA #REQUIRED
ID全局唯一标识符id ID #REQUIRED
IDREF引用另一个元素的 IDstudent_ref IDREF #REQUIRED
IDREFS引用多个 ID(空格分隔)refs IDREFS #IMPLIED
NMTOKEN单个有效名称标记country NMTOKEN #REQUIRED
枚举从指定列表中选一gender (male|female) #REQUIRED

默认值修饰符

修饰符含义XML 中可以省略吗?
#REQUIRED必填否
#IMPLIED可选,无默认值可以
#FIXED "value"固定值,不能改可以(自动取固定值)
"default"有默认值可以(不写则取默认值)

完整示例:黄俪设计选课系统的 DTD

场景说明

飞翔科技的测试工程师 黄俪 负责验证学生选课系统的 XML 数据。她设计了一套 DTD,利用 ID/IDREF 确保"学生选课"数据的一致性——每个选课记录引用的学生和课程 ID 都必须存在。

操作前:无约束的 XML

<?xml version="1.0" encoding="UTF-8"?>
<university>
  <student id="S001" name="小崔"/>
  <student id="S002" name="黄俪"/>
  <course id="CS301" name="XML技术"/>
  <course id="CS402" name="Java高级"/>
  <!-- 引用了不存在的 student id="S999" -->
  <enrollment student_id="S999" course_id="CS301"/>
</university>

操作后:DTD 属性声明 + ID/IDREF

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE university [
  <!ELEMENT university (student*, course*, enrollment*)>

  <!ELEMENT student EMPTY>
  <!ATTLIST student
    id ID #REQUIRED
    name CDATA #REQUIRED
    major CDATA #IMPLIED
    status (active|graduated|suspended) "active">

  <!ELEMENT course EMPTY>
  <!ATTLIST course
    id ID #REQUIRED
    name CDATA #REQUIRED
    credits CDATA #REQUIRED
    semester (spring|fall|summer) #REQUIRED>

  <!ELEMENT enrollment EMPTY>
  <!ATTLIST enrollment
    student_ref IDREF #REQUIRED
    course_ref IDREF #REQUIRED
    grade CDATA #IMPLIED>
]>
<university>
  <student id="S001" name="小崔" major="计算机科学"/>
  <student id="S002" name="黄俪" major="软件工程" status="active"/>
  <course id="CS301" name="XML技术" credits="3" semester="fall"/>
  <course id="CS402" name="Java高级" credits="4" semester="spring"/>

  <enrollment student_ref="S001" course_ref="CS301" grade="A"/>
  <enrollment student_ref="S002" course_ref="CS301"/>
  <enrollment student_ref="S002" course_ref="CS402" grade="B+"/>
</university>

操作结果

DTD 验证器在解析过程中会执行以下检查:

  1. 每个 student/@id 和 course/@id 全局唯一(ID 类型保证)
  2. 每个 enrollment/@student_ref 引用的 ID 必须存在于文档中的 student/@id(IDREF 检查)
  3. status 只能取 active、graduated、suspended 之一,省略时默认为 active
  4. semester 只能取 spring、fall、summer 之一

黄俪测试时发现:如果 XML 中有 student_ref="S999",DTD 验证会直接报错——"引用的 ID 不存在"。

易错场景

错误一:ID 值以数字开头

<!-- ❌ ID 类型要求值是合法的 XML 名称(不能以数字开头) -->
<student id="001" name="小崔"/>

<!-- ✅ 加前缀 -->
<student id="S001" name="小崔"/>

错误二:混淆 #IMPLIED 和 #FIXED

<!ATTLIST element attr1 CDATA #IMPLIED>   <!-- 可选,无默认值 -->
<!ATTLIST element attr2 CDATA #FIXED "x">  <!-- 固定为 "x",写别的值就报错 -->

错误三:枚举值没有引号

DTD 属性声明中,枚举值和默认值都不需要引号,这与 XML 文档中属性值必须加引号不同。

<!-- ✅ DTD 声明中 -->
<!ATTLIST course semester (spring | fall) #REQUIRED>
<!-- ✅ XML 文档中 -->
<course semester="spring"/>

面试考点

考点参考答案要点
DTD 中 #REQUIRED、#IMPLIED、#FIXED 的区别?#REQUIRED 必填;#IMPLIED 可选且无默认值;#FIXED 固定值,不能在 XML 中修改
ID 和 IDREF 如何实现数据完整性?ID 保证元素有全局唯一标识符;IDREF 引用其他元素的 ID,验证器会检查引用目标是否存在——类似数据库外键
CDATA 属性类型在 DTD 和 XML 中分别是什么含义?在 DTD 中 CDATA 是属性类型(表示字符数据);在 XML 中 CDATA 是转义块(<![CDATA[...]]>)。同名不同义
上一页
DTD 元素声明
下一页
DTD 实体声明