XML DTD 实体 - 嵌套声明

XML DTD Entities - nested declarations

是否可以使用嵌套的 XML DTD 实体声明?我做了一些研究,但找不到满足我要求的解决方案。

我目前使用的是:

<!DOCTYPE test [
<!ENTITY system "SystemA">
<!ENTITY path SYSTEM "file:./path/to/SystemA">
<!ENTITY config_file SYSTEM "file:./config/for/SystemA.config">
]>

因为“SystemA”已经在变量 system 中声明,我宁愿使用声明的变量 system 而不是使用“ SystemA" 在所有后续声明中。

如果您只想将一般实体扩展到文件路径作为正文内容中的文本字符串,您可以立即执行此操作:

<!ENTITY system "SystemA">
<!ENTITY path "&system;.config">

但是,如果您想从 .config 文件中获取标记声明,使它们成为 DTD 的一部分,那么您需要一个外部实体声明(正如您已经知道的那样)。要在 声明(相对于内容)中使用文本替换,您必须使用 参数实体 而不是一般实体。参数实体使用百分号声明(注意声明中百分号后面的 space,而参数实体 references 必须有 none;

<!ENTITY % paramentity "SystemA">

现在您可以使用 %paramentity; 替换字符串 SystemA 在标记声明中 ;

<!ELEMENT x ..,>
%paramentity;

虽然上面会给出错误,因为字符串 SystemA(或任何其他字符数据)不允许出现在 DTD/the 文档序言中。

不过还有一个问题:参数实体引用不会在标识符文字中扩展,所以这有效:

<!ENTITY % myent  SYSTEM "%paramentity;/f.config">

相反,字符串 %paramentity;/f.config 被逐字用作 %myent; 的替换值。要从参数实​​体构建系统标识符,您应该将文字标记作为一个整体来定位:

<!ENTITY % sysid "'filename'">
<!ENTITY file SYSTEM %sysid;>

XML 的这种行为是由于 SGML(XML 作为子集从中导出)。具体来说,SGML 设置了一些限制,其中参数实体扩展可以出现在文档序言中(或者,对于 SGML 但不是 XML 没有这些)也在内容中的标记声明中(例如标记的部分声明) . SGML 这样做是为了防止混淆使用标记。