DTD 元素 vs 属性
DTD 考量:元素与属性
Section titled “DTD 考量:元素与属性”在设计 XML 文档的结构时(结构可以形式化(formalized)为 DTD 或 Schema),你需要决定是使用子元素还是属性来表示信息片段。
如前所述,没有严格的 XML 语法规则来规定这种选择,但 DTD/Schema 设计原则和最佳实践提供了指导。
让我们回顾 person 示例:
用于 gender 的属性:
<person gender="female"> <firstname>Anna</firstname> <lastname>Smith</lastname></person>用于 gender 的元素:
<person> <gender>female</gender> <firstname>Anna</firstname> <lastname>Smith</lastname></person>两者都是有效的 XML 并传达相同的信息。选择会影响结构、验证能力(尤其是在使用 XSD 时)和处理的便利性。
选择指南(重申)
Section titled “选择指南(重申)”这些指南有助于做出一致且合乎逻辑的选择:
- 元素用于:
-
- 核心数据内容。
-
- 可能包含结构的信息(例如,地址、日期组成部分)。
-
- 可以出现多次的信息(例如,电话号码、电子邮件地址)。
-
- 未来可能需要扩展更多细节的数据。
-
- 当一个元素关联的信息片段过多时,用于提高可读性。
属性用于:
-
- 元数据(关于数据的信息,例如,
xml:id、unit、language、status)。
- 元数据(关于数据的信息,例如,
-
- 不需要结构的简单、原子值。
-
- 控制处理或呈现(例如,
type、role)。
- 控制处理或呈现(例如,
再次考虑日期示例:
属性(推荐 ISO 8601 格式):
<note date="2024-07-01"> ...</note>结构化元素(通常因灵活性而优先选择):
<note> <date> <year>2024</year> <month>07</month> <day>01</day> </date> ...</note>结构化元素的方法使得单独查询或处理年、月或日变得更容易。
DTD/Schema 的影响
Section titled “DTD/Schema 的影响”你的选择会影响你在 DTD 或 Schema 中定义结构的方式:
- DTD 中的属性: 使用
<!ATTLIST ...>声明定义,指定属性名称、类型(例如,CDATA、ID、IDREF、枚举类型)以及默认值/要求(#REQUIRED(必需)、#IMPLIED(可选))。 - DTD 中的元素: 使用
<!ELEMENT ...>声明定义,指定元素名称及其允许的内容模型(content model)(例如,其他元素、#PCDATA、EMPTY)。 - XML Schema (XSD): 为元素和属性提供了更丰富的功能,包括精确的数据类型(整型、日期型、布尔型、模式匹配)、出现约束(occurrence constraint)(最小/最大出现次数)以及更复杂的结构。在元素/属性之间的选择在使用 XSD 时可能具有更重要的验证影响。
虽然 DTD 有其局限性(例如,属性的基本类型检查、不支持命名空间),但这个基本决定会影响你如何声明你预期的结构。
避免给元素添加过多的属性,因为它会损害可读性和可维护性:
可读性较差的示例:
<note to="Tove" from="Jani" date="2024-07-01" priority="high" status="unread" ... />像 priority 或 status 这样的元数据可能适合作为属性,但像 to、from、date 这样的核心内容通常更适合作为元素。
元数据的例外:标识符
Section titled “元数据的例外:标识符”如之前强调的,使用属性作为唯一标识符是一种标准且推荐的做法。为此目的使用 xml:id 属性。
<messages xmlns:xml="http://www.w3.org/XML/1998/namespace"> <note xml:id="p501"> <to>Tove</to> ... </note> <note xml:id="p502"> <to>Jani</to> ... </note></messages>xml:id 属性明确指定了一个用于引用元素的唯一标识符,符合元数据的定义。
总之,优先使用元素表示内容和结构,而将属性用于元数据、标识符和简单配置标志。