Skip to content

DTD 元素

在文档类型定义 (DTD) 中,元素声明定义了允许的元素名称,并指定了每个元素可以包含什么内容。

提示:虽然 DTD 定义了基本结构,但 XML Schema (XSD) 是定义 XML 约束的现代、更强大的标准,包括丰富的数据类型。

在 DTD 中声明元素的基本语法是:

<!ELEMENT elementname contentmodel>

elementname 是你正在定义的 XML 标签的名称。 contentmodel 指定元素允许包含何种类型的内容。

必须不包含任何内容(文本或子元素)的元素使用关键字 EMPTY 进行声明。

DTD 声明:

<!ELEMENT img EMPTY>

有效的 XML 示例:

<img src="image.png" alt="Logo"/>

无效的 XML 示例:

<img>Some Text</img> <!-- Error: img must be empty -->

注意:空元素仍然可以有属性。

设计用于仅包含可解析字符数据(文本,可能包含对实体的引用)的元素使用括号内的 #PCDATA 关键字。

DTD 声明:

<!ELEMENT title (#PCDATA)>

有效的 XML 示例:

<title>Learning XML Basics</title>

无效的 XML 示例:

<title>Chapter 1 <section>Intro</section></title> <!-- Error: Cannot contain child elements -->

要允许元素包含文本和任何已声明子元素的任意组合(一个非常宽松的定义),请使用 ANY 关键字。通常不推荐这样做,而应优先使用更具体的内容模型。

DTD 声明:

<!ELEMENT description ANY>

有效的 XML 示例:

<description>Just text.</description>
<description><para>Paragraph</para> and <bold>bold</bold> text.</description>
<description/>

声明包含子元素(序列)的元素

Section titled “声明包含子元素(序列)的元素”

要指定元素必须包含特定序列的子元素,请将子元素名称列在括号内,用逗号分隔。

DTD 声明(假设 to、from、heading、body 也已被声明):

<!ELEMENT note (to, from, heading, body)>

有效的 XML 示例:

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget!</body>
</note>

无效的 XML 示例:

<note><from>Jani</from><to>Tove</to>...</note> <!-- Error: Wrong order -->
<note><to>Tove</to><from>Jani</from><heading>Reminder</heading></note> <!-- Error: Missing body -->

列出的每个子元素必须且只能出现一次,并按指定的顺序。

你可以使用放在元素名称或组后面的出现次数指示符来控制一个子元素(或一组元素)必须出现的次数:

  • 无指示符: 必须恰好出现一次(如上面的序列示例)。
  • +(加号): 必须出现一次或多次。
  • *(星号): 可以出现零次或多次(可选,可重复)。
  • ?(问号): 可以出现零次或一次(可选)。

示例:

<!ELEMENT email (to+, from, subject?, cc*, body)>
<!-- Meaning:
- One or more 'to' elements
- Exactly one 'from' element
- Zero or one 'subject' element
- Zero or more 'cc' elements
- Exactly one 'body' element
-->

要允许元素包含列表中可能选项中的一种选择,请在括号内使用竖线 | 符号分隔选项。

DTD 声明:

<!ELEMENT contact (email | phone | address)>
<!-- Meaning: A contact element must contain exactly one of: an email, a phone, OR an address element -->

你可以使用括号进行分组,将选择与序列和出现次数指示符结合起来:

<!ELEMENT person (name, (email | phone)?, address*)>
<!-- Meaning: name (required), then optionally an email OR a phone, then zero or more addresses -->

混合内容允许元素同时包含文本(#PCDATA)和子元素,顺序和次数任意。这通常用于文档类结构(例如,包含粗体或斜体文本的段落)。

语法要求 #PCDATA 必须是选择列表中的第一项,后跟允许的子元素名称,它们都用 | 分隔,并且整个组后跟 *。

DTD 声明(假设 b 和 i 元素也已被定义):

<!ELEMENT paragraph (#PCDATA | b | i)*>

有效的 XML 示例:

<paragraph>This is **bold** text and this is <i>italic</i>.</paragraph>
<paragraph>Just text.</paragraph>
<paragraph>**Only bold**.</paragraph>

注意:使用混合内容时,你将无法控制文本中子元素的顺序和确切数量。