请注意,“有效的 SGML DTD”在技术上有点模棱两可:它取决于使用哪个“SGML 声明”,这是指定名称的最大长度,甚至名称中可以出现哪些字符的地方。那是在特定 DTD 中使用的“具体语法”(因此在特定的 SGML 文档中)。
SGML 的“默认”语法称为“参考具体语法”,在 ISO 8879:1986 中定义。因为在这个语法中名字的最大长度(所谓的“ NAMELEN 数量”)被设置为 8(八),而 LOW LINE ( _
) 不能用在名字中(不是所谓的名字字符),您的 DTD对于参考具体语法是无效的。
例如,HTML 使用自己的SGML 声明:它极大地增加了NAMELEN 数量并添加_
到名称字符,以及其他更改。对于这种具体的语法,您的 DTD 在语法上确实是有效的。
但是没有元素声明,channel_name
但 DTD 要求至少存在一个这样的元素tvguide
(即包含在所需的元素中channel
)。[省略文档中未出现的元素类型的声明本身不是错误或问题。]
因此,从您不能编写任何根据它有效的文档元素(即tvguide
元素或简单的“文档”)的意义上说,DTD 不是(还)“有效的”。
channel_name
为like添加一个简单的声明
<!ELEMENT channel_name (#PCDATA)>
补救措施——现在例如文档元素
<tvguide>
<date>2016</date>
<channel><channel_name>XTV</channel_name></channel>
</tvguide>
根据您的 DTD是有效的。(我使用另一个答案中提到的 SP 解析器进行了尝试。)
简化 DTD 中的名称将使整个内容成为有效的“基本 SGML 文档”,甚至是有效的“最小 SGML 文档”——这些术语(同样来自 ISO 8879)在没有具体说明时最接近“有效 SGML”的概念给出了上下文和 SGML 声明:它们基本上意味着“任何 SGML 系统都可以移植和接受”。这是我建议的版本:
<!DOCTYPE tvguide [
<!ELEMENT tvguide - - (date,channel+)>
<!ELEMENT date - - (#PCDATA)>
<!ELEMENT channel - - (ch-name,format?,program*)>
<!ATTLIST channel
teletext (yes|no) no>
<!ELEMENT format - - (#PCDATA)>
<!ELEMENT ch-name - - (#PCDATA)>
<!ELEMENT program - - (name,start-tm,(end-tm|duration))>
<!ATTLIST program
min-age CDATA #REQUIRED
lang CDATA "es">
<!ELEMENT name - - (#PCDATA)>
<!ELEMENT start-tm - - (#PCDATA)>
<!ELEMENT end-tm - - (#PCDATA)>
<!ELEMENT duration - - (#PCDATA)>
]>
<tvguide>
<date>2016-12-11</date>
<channel><ch-name>X-TV 4</ch-name></channel>
</tvguide>