3

我正在编写一个 DTD 解析器,我有点不确定如何扩展参数实体。例如,这个 DTD 摘录是否有效?

<!ENTITY % xx '&#37;zz;'>
<!ENTITY % zz '&#60;!ENTITY tricky "error-prone" >' >
<!ENTITY % abcd '%xx;'>
<!ENTITY % ef 'c'>
<!ENTITY % gh '%ab%ef;d;'>
%gh;

更具体地说,我很想知道实体 gh 是否会正确扩展。在我看来 %ef; 应该首先扩展为“c”,然后是新形成的 PE 引用 %abcd;应该扩展到 %xx; 等等。

我见过的大多数解析器都将 %ab 识别为 PE 引用并且由于未定义该 PE 而失败。但是我发现标准中绝对没有参考要求解析器以这种方式工作。我发现的唯一参考是Included in Literal,而不是Included as PE,它指出替换文本必须用一个前导和一个0x20 后一个0x20 放大 - 但不是在文字中。

任何指针?谢谢你。

4

1 回答 1

2

本题示例代码的第一行取自W3C XML 推荐中的这个示例,所以那些不熟悉 DTD 转义相当复杂的逻辑的人应该看看那里写的解释。

更具体地说,我很想知道实体 gh 是否会正确扩展。

不,不会的。原因是您对参数实体的定义gh有格式错误的语法。参数实体定义的语法是:( ref )

PEDecl   ::=    '<!ENTITY' S '%' S Name S PEDef S? '>'
PEDef    ::=    EntityValue | ExternalID

实体值的语法是:( ref )

EntityValue   ::=       '"' ([^%&"] | PEReference | Reference)* '"'
                        |  "'" ([^%&'] | PEReference | Reference)* "'"

“PEReference”是参数实体引用 ( %Name;),“Reference”是一般实体引用 ( &Name;) 或字符引用 (&#123;&#x7B)。(参考

这里[^%&"][^%&']意思是实体值不能包含%字符,除非它表示(参数实体)名称产生的开始。并且由于%不是有效的名称字符,而是出现在名称产生结束字符之前;,字符序列%ab%会导致错误。我会说如果第一个%符号被替换为字符引用它应该可以工作,那么%ef;实体替换在%ab...被视为对参数实体名称的引用之前完成。

于 2011-11-25T07:48:51.900 回答