问题描述
DTD 提供了一种引用任意格式的外部实体的机制,从而允许 SGML 和 XML 文件链接到具有 URI 的任何文件,而无需为此创建自定义机制。因此,例如,可以在 DTD 中指定:
<!ELEMENT img EMPTY>
<!ATTLIST img src ENTITY #required>
<!NOTATION gif PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN" "image/gif">
<!ENTITY myimg1 SYstem "img1.gif" NDATA gif>
<!ENTITY myimg2 SYstem "img2.gif" NDATA gif>
<!ENTITY myimg3 SYstem "img3.gif" NDATA gif>
创建 img
元素时,可以使用 myimg1
之类的值,并且应该通知处理文档的应用程序引用文件 img1.gif
,具有特定格式。
按照我的理解,这样做有三个好处:
- 标准化。不管使用的任何实际模式,应用程序都可以找出文档链接到的所有内容,即使它可能不理解它。这可能对安全、搜索、过滤等有用。
- 避免重复。实体 URI 只定义一次,但可以多次引用。
- 指定实体旁边的格式(符号)。如果系统不提供或不知道格式,或者有多种格式或显示方式可供选择(例如显示或下载),则无需用这些信息将文档弄得乱七八糟。
然而,到目前为止,我还没有找到任何主要使用这种机制的数据集或应用程序。在实践中,所有这些点都被击败了:
- 绝大多数资源仍然以特定于模式的方式链接,例如在 XHTML 中。 XLink 用于以 XML 方式标准化资源链接。 XML 架构定义了
anyURI
,因此仍然可以自动找到链接(但嵌入和链接到资源之间存在差异)。 - 内部解析的实体已经可以提供一种在文档的任何位置重用 URI 的方法。压缩进一步减少了关注数据集中较大文档的需要。
- 使用最广泛的 HTTP 提供了指定或协商目标文件格式的方法。这有一个优点,即服务器不会被锁定为仅以特定格式存储文件;例如,它可以升级到更好的图像格式(即 PNG 而非 GIF),而无需修改任何引用它的文档。
我发现的所有有关此机制的教程都简单地说明了它的用途(主要是从其他文档中复制段落),并附有上述自定义 DTD 的示例。此外,由于这样的实体只能包含在属性中,因此它实际上永远不能被视为任何元素内容的一部分,其处理始终取决于应用程序。
是否有使用或依赖外部实体和符号的系统?是否有应用程序可以识别以这种方式使用的实体并能够理解符号?我可以合理使用什么样的符号公共 ID,系统 ID 的一些实际示例是什么?实体或符号是否有通用的公共 ID?
解决方法
未解析的实体(和符号)很少使用,但我确信有一些 SGML 顽固派在某处使用它们。这不是我会选择使用的机制,原因有二:工具不能很好地支持它,而且不是很灵活。
您的标题问题询问了外部未解析实体,但以下一些散文更一般地讨论了外部实体。外部解析的实体肯定比未解析的实体使用得更广泛(尽管存在安全问题),我当然与使用它们的系统一起工作。但我不会选择使用它们; XLink
和 XInclude
更加灵活。
DocBook 和 TEI 主要使用符号和未解析的实体。
它们还用于我的 SGML 软件 (http://sgmljs.net) 中的通用模板/参数化宏扩展机制,非常符合在没有新语法的情况下向 SGML 添加功能的精神。具体来说,在 SGML(但不是 XML)中,实体声明可以具有数据属性,如
<!ENTITY e SYSTEM "..." NDATA sgml [ x=1 y=2 ]>
对 XLink/XInclude 的支持通常与实体/符号声明一样参差不齐,甚至可以说甚至更多,因为后者是核心 SGML/XML 构造(参见例如 Trying to use XInclude with Java and resolving the fragment with xml:id)。 XInclude 更严重的问题是它以意想不到的方式 (XInclude Schema/Namespace Validation?) 与模式验证交互,因为它被分层为 XML 应用程序/词汇而不是核心功能。
XLink 在纸面上可能很好(我认为它甚至不是,因为它盲目地引入了没有上下文的 HyTime 概念,例如,除了纯 HTML 类链接之外,链接角色的规范非常模糊)。但现实情况是,迄今为止最常见的文档格式(即 HTML)使用了 XML 根本无法合理处理的 URL,因为它允许并且经常包含 XML 一直想要的 &
&符号解释为实体引用的开始。 SGML 的 WebSGML 修订版(由原始 XML 规范的作者创建,同时引入 XML 作为 SGML 的独立子集以对齐这两个规范)引入了数据规范属性(在 {{3} }) 做专门处理这个问题。
更新:关于在 SGML 和 XML 中使用的符号的常用公共标识符,有
-
历史悠久、已撤销的 ISO/IEC 9070 规范及其定义的标识符 (见http://sgmljs.net/docs/parsing-html-tutorial/parsing-html-tutorial.html)
-
较旧的 ISO HTML 4 规范 (ISO/IEC 15445) 为 (ISO) HTML 分配替代公共标识符,而不是 W3C HTML 4 的众所周知的标识符(请参阅 http://xml.coverpages.org/wg4-n1990.html)
-
ISO/IEC 10744 (HyTime 2nd ed) 的存储符号标识符,尽管这些实际上仅用于正式系统标识符(参见例如 http://www.cs.tcd.ie/misc/15445/15445.dtd 以获得解释),其中包括通过 MIME/IANA 媒体类型关联定义用作查看器应用程序的外部程序的符号的约定
-
在 ISO/IEC 8879:1986 技术勘误表 2(又名 WebSGML 又名附件 K)中建立新标识符的约定,将唯一标识符的形成委托给域名解析;例如
的表示法+//IDN www.someisp.net/users/mtb
指的是其规范文档位于规范位置http://www.someisp.net/users/mtb
还有众所周知的 SGML、HTML 和 XML(特别是 MathML)中特殊字符的实体集。