XML ID属性需以字母开头的原因、DTD日期优化及NCName报错咨询
XML与DTD相关问题解答
1. XML的ID属性是否必须以字母开头?
是的。根据XML规范,ID属性的取值必须是NCName(非冒号名称),NCName的规则明确要求:
- 必须以字母(a-z、A-Z)或下划线(_)开头
- 后续字符可以是字母、数字、下划线、连字符(-)、点号(.)
像dd/mm/yyyy这种以数字开头且包含斜杠(/)的字符串,完全不符合NCName规则,作为ID属性值时必然会触发验证错误。
2. DTD中是否存在比CDATA更合适的日期类型定义方式?
DTD的类型系统非常有限,没有内置的日期专属类型。可选方案分两种:
- 若能切换到XML Schema(XSD),XSD提供了
xs:date、xs:dateTime等专门的日期类型,可严格约束格式与合法性 - 若必须使用DTD,只能近似处理:
- 使用
NMTOKEN类型:但NMTOKEN不允许斜杠、空格等字符,不适用于带分隔符的日期格式 - 保留
CDATA类型,在应用层面自行验证日期格式正确性 - 枚举所有可能的日期值:仅适用于日期范围极小的场景,实用性极低
- 使用
3. DTD中ID与NCName混用的语法错误问题
你写的代码<!ATTLIST dailyProgrammation data ID NCName #REQUIRED>存在语法错误:ID本身就是DTD预定义的属性类型,不能同时指定NCName作为类型。
正确写法分两种场景:
- 如果要将
date定义为ID属性:
<!ATTLIST dailyProgrammation date ID #REQUIRED>
注意:此时XML中的date属性值必须符合NCName规则,比如把28/11/2003改成d_28112003这类以字母/下划线开头且不含特殊字符的格式。
- 如果只是想约束属性值为NCName类型(不需要ID的唯一性约束):
<!ATTLIST dailyProgrammation date NCName #REQUIRED>
但NCName不允许斜杠,带分隔符的日期格式仍然不符合要求。
修正后的完整示例
XML代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE TVchannel SYSTEM "TVchannel.dtd"> <TVchannel> <dailyProgrammation date="d_28112003"> <programs> ... </programs> </dailyProgrammation> </TVchannel>
DTD代码(定义ID属性)
<!ELEMENT TVchannel(dailyProgrammation)> <!ELEMENT dailyProgrammation(programs?)> <!ATTLIST dailyProgrammation date ID #REQUIRED>
内容的提问来源于stack exchange,提问作者Matteo Cancian
相关产品推荐
相关产品推荐

