在 !DOCTYPE 末尾使用 [] 时 XML 的差异?

Difference in XML when using [] at end of !DOCTYPE?

正如您在链接问题中看到的那样,在 C# 中使用 XDocument 时,空的内部子集 [] 将被添加到 DTD-Header 中,如果之前不存在的话。问题和答案处理如何删除这个,但是,而回答者指出这是well-formatted XML,我问:

1) 在什么情况下会出现问题?哪个标准发生了变化,以至于遗留应用程序可能与空的内部子集不兼容?

2) 在新应用程序中使用空的内部子集是否更可取?

当您使用 XDocument 和 DTD 解析 Xml 文档时,然后为空 Internal Subset 表示自动插入方括号 []

如果你想删除这个 Internal Subset 那么你可以像

一样设置 XDocumentType.InternalSubset = null
XDocument doc = XDocument.Load(@"Path to xml file");
if (doc.DocumentType != null)
    doc.DocumentType.InternalSubset = null;

//Do code with XDocument

示例:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE book [ <!ENTITY h "hardcover"> ]>
<book genre="novel" ISBN="1-861001-57-5">  
  <title>Pride And Prejudice</title>
  <author>Mark Henry</author>  
</book>

在上面的例子中,请注意这部分[ <!ENTITY h "hardcover"> ]。这称为内部子集。

重要吗?

不,这没关系。但它是一个格式正确的 XML 如果您的 XML 不包含任何内部子集,那么它表示为空白方括号 []。这意味着您的 xml 不包含任何内部子集。

在使用没有内部子集的 XDocument 解析 xml 时,XDocument 会附加空白方括号 [] 而不是在 DOCTYPE 中不显示任何内容。

空的内部子集有什么作用?

内部实体的基本目的是避免重复输入相同的内容(如组织名称)。相反,我们可以定义一个内部实体来包含文本,然后您只需要在要插入文本的地方使用该实体。因为实体是由解析器扩展的,所以您可以放心,您将在每个位置获得相同的文本。如果您拼错了实体名称,解析器也会捕获。

您可以阅读有关内部子集的更多信息here

有点奇怪,但没有错

DOCTYPE 的语法是

doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'   
intSubset   ::= (markupdecl | DeclSep)*

因此,您可以在方括号之间进行一系列零个或多个标记声明,如果没有任何标记声明,则可以省略方括号(但不是必须的)。