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

时间:2018-11-13 12:08:56

标签: c# xml linq-to-xml dtd doctype

正如您在链接的问题中所看到的,在C#中使用XDocument时,如果以前不存在空的内部子集[],则会在DTD标头中添加该子集。问题与答案涉及如何删除此内容,但是,而回答者指出这是格式正确的XML,我问:

1)在什么情况下会引起问题?更改了哪个标准,以便旧版应用程序可能与空的内部子集不兼容?

2)是否最好在新应用程序中使用空的内部子集?

2 个答案:

答案 0 :(得分:1)

当您将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中不显示任何内容。

一个空的内部子集做什么?

内部实体的基本目的是避免一次又一次键入相同的内容(如组织的名称)。相反,我们可以定义一个内部实体来包含文本,然后只需要在要插入文本的位置使用该实体。由于该实体是由解析器扩展的,因此可以确保在每个位置都会得到相同的文本。如果您拼错实体名称,解析器也会捕获。

您可以了解有关内部子集Windows Error Reporting

的更多信息

答案 1 :(得分:0)

有点奇怪,但没错。

DOCTYPE的语法是

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

因此,您可以在方括号之间使用一系列零个或多个标记声明,并且如果没有任何标记声明,则可以省略方括号(但不必这样做)。