我正在编写DTD解析器,我有点不确定如何扩展参数实体。例如,此DTD摘录有效吗?
<!ENTITY % xx '%zz;'>
<!ENTITY % zz '<!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 - 但不是文字。
任何指针? 谢谢。
答案 0 :(得分:2)
此问题的示例代码的第一行取自W3C XML建议中的this example,因此那些不熟悉DTD转义的错综复杂逻辑的人应该看到写在那里的解释
更具体地说,我很想知道实体gh是否会扩展 正确。
不,它不会。原因是您对参数实体gh
的定义语法不正确。参数实体定义的语法是:(ref)
PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
PEDef ::= EntityValue | ExternalID
和实体值的语法是:(ref)
EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
| "'" ([^%&'] | PEReference | Reference)* "'"
“PEReference”是参数实体引用(%Name;
),“引用”是一般实体引用(&Name;
)或字符引用({
或{{1} })。 (ref)
此处{
和[^%&"]
表示实体值不能包含[^%&']
字符,除非它表示(参数实体)名称生成的开头。并且因为%
不是有效的名称字符,但它出现在名称生成结束字符%
之前,字符序列;
将导致错误。我会说如果用字符引用替换第一个%ab%
符号它应该有效,那么%
实体替换在%ef;
被视为对参数实体的引用之前完成名。