内部 DTD 中的参数实体

Mat*_*ert 5 xml dtd

我有以下内容simple.dtd

<!ENTITY % placeholder "my, element, list">
<!ELEMENT root (%placeholder;)>
<!ELEMENT my (#PCDATA)>
<!ELEMENT element (#PCDATA)>
<!ELEMENT list (#PCDATA)>
Run Code Online (Sandbox Code Playgroud)

simple.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE root SYSTEM "simple.dtd">

<root>
    <my />
    <element />
    <list />
</root>
Run Code Online (Sandbox Code Playgroud)

这有效并且有效。

但完全相同的 DTD 内联:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE root [
        <!ENTITY % placeholder "my, element, list">
        <!ELEMENT root (%placeholder;)>
        <!ELEMENT my (#PCDATA)>
        <!ELEMENT element (#PCDATA)>
        <!ELEMENT list (#PCDATA)>
]>

<root>
    <my />
    <element />
    <list />
</root>
Run Code Online (Sandbox Code Playgroud)

失败并出现错误:

$ xmllint --valid simple.xml
simple.xml:4: parser error : ContentDecl : Name or '(' expected
        <!ELEMENT root (%placeholder;)>
                        ^
simple.xml:4: parser error : expected '>'
        <!ELEMENT root (%placeholder;)>
                        ^
Entity: line 1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration

 %placeholder; 
              ^
Entity: line 1: 
my, element, list
^
Entity: line 1: parser error : DOCTYPE improperly terminated
 %placeholder; 
              ^
Entity: line 1: 
my, element, list
^
Entity: line 1: parser error : Start tag expected, '<' not found
 %placeholder; 
              ^
Entity: line 1: 
my, element, list
^
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?

Ond*_*cny 4

在DTD 的内部子集中,标记声明中不允许引用参数实体。您必须使用外部 DTD,即单独的文件。这在此处的XML 规范中被记录为格式良好约束。