XML中的“standalone”指令是什么意思?

320
在XML文档中,'standalone'指令是什么意思?

1
被接受的答案包含了一个事实错误,这也是我写出自己更好的答案的原因。但是,作者随后更新了他的答案以删除我暗示的错误,从而确保了未来的声誉。这让我有点不舒服,因为感觉赞数被这样偷走了。虽然这是多年前发生的小事,但我仍然觉得这有点让人失去动力。 - Rinke
那么你希望接受的答案仍然是错误的,误导人们吗? - Mark Fisher
1
@MarkFisher 不,我想让我的答案成为被采纳的答案。 - Rinke
5个回答

230
standalone声明是告诉解析器忽略DTD中的任何标记声明的一种方式。此后,DTD仅用于验证。
以一个简单的<img>标签为例。如果查看XHTML 1.0 DTD,就会发现有一个标记声明告诉解析器<img>标签必须为空,并具有srcalt属性。当浏览器遍历XHTML 1.0文档并找到<img>标签时,它应该注意到DTD需要srcalt属性,并在它们不存在时添加它们。它也会自动关闭<img>标签,因为它应该为空。这就是XML规范所说的“标记声明可能影响文档内容”的含义。然后可以使用standalone声明告诉解析器忽略这些规则。
无论您的解析器是否实际执行此操作都是另一个问题,但符合标准的验证解析器(如浏览器)应该执行此操作。
请注意,如果您没有指定DTD,则独立声明“没有意义”,因此除非您还指定了DTD,否则没有使用它的理由。

11
这个例子需要进一步修改。在XML中,使用“standalone='no'”通常不会关闭未关闭的XML标记(这是SGML的一个特性,但不是XML的特性)。这样做将导致验证失败。它也无法提供必需属性的值。 - khaemuaset
3
“独立声明”是告诉解析器忽略DTD中的任何标记声明的一种方法。但这并不正确。使用“standalone=yes”,标记声明不会被忽略,相反它们会使文档无效。您介意我将其编辑到答案中吗? - sleske
@sleske 请只做这个更改。如果作者不满意,他/她总是可以回退的。 - Stephan
@Stephan:感谢你的鼓励。不幸的是,我已经不再了解整个XML相关的内容,所以我现在不能自信地进行编辑。如果你有最新的知识,请随意进行编辑 :-)。 - sleske

133
  • standalone指令是XML声明上的可选属性。
  • 有效值为yesno,其中no是默认值。
  • 该属性仅在使用DTD时才相关。(使用模式而非DTD时,该属性无关紧要。)
  • standalone="yes"表示XML处理器仅需使用DTD进行验证。在这种情况下,它将不用于以下内容:
    • 属性的默认值
    • 实体声明
    • 规范化
  • 请注意,如果文档使用外部DTD,则standalone="yes"可能会添加有效性约束。当文档包含需要修改XML的内容(例如属性的默认值),并且使用了standalone="yes",则文档无效
  • standalone="yes"可以帮助优化文档处理的性能。

来源:如果使用DTD,则独立伪属性只有相关


2
使用standalone="yes"将导致额外的有效性约束(即可能导致XML文档无效)。我将其编辑到答案中,希望这样可以。 - sleske
2
@sleske感谢您的贡献。我尝试简化了您的编辑,同时仍然清楚地表达了您的观点。如果我理解有误,请随时再次编辑。 - Rinke
据我所知,standalone="yes" 指定 XML 内容不能有任何影响的_外部_标记声明。也就是说,standalone="yes" 的文档可能具有内部 DTD 子集,用于声明属性默认值和实体声明,并且进一步在内容中引用。 - Stanimir Stamenkov

21

standalone 描述当前的 XML 文档是否依赖于外部标记声明。

W3C 在 "可扩展标记语言(XML) 1.0(第五版)" 中描述了其目的:


19

standalone=yes声明的目的是保证文档中的信息可以只基于内部DTD被准确地检索,即文档可以“独立”存在而不需要外部引用。对一个独立文档进行验证可以保证非验证处理器有所有可用信息来正确解析文档。

如果一个文档没有外部DTD,并且内部DTD中没有参数实体引用,则独立声明没有任何作用,因为这些文档已经隐式地是独立的。

下面是使用standalone=yes的实际效果:

  • 当解析具有外部DTD或参数实体引用的文档时,强制处理器抛出错误,如果文档包含在内部DTD中未声明的实体引用(其中参数实体替换文本是非验证处理器不必解析的例外),ampltgtaposquot是唯一的例外。

  • 当解析非独立声明的文档时,非验证处理器可以自由停止解析内部DTD,只要遇到一个参数实体引用。声明一个文档为独立的,强制非验证处理器即使在忽略一个或多个参数实体引用后,也要解析内部DTD中的标记声明。

  • 如果在文档中找到以下任何内容,并且它们的相应声明在外部DTD或参数实体替换文本中,则强制验证处理器抛出错误:

    • 具有默认值的属性,如果没有明确提供它们的值
    • 实体引用(除了ampltgtaposquot
    • 具有标记类型的属性,如果该属性的值会被规范化修改
    • 具有元素内容的元素,如果其内容中出现任何空格

一个非验证处理器可能会考虑检索外部DTD并扩展所有参数实体引用,用于非独立的文档,即使它没有义务这样做,也就是说,设置standalone=yes理论上可以提高非验证处理器的性能(剧透:这可能不会有什么影响)。


这里的其他答案要么不完整,要么不正确,主要误解在于

独立声明是告诉解析器忽略DTD中的任何标记声明的方法。之后,DTD仅用于验证。


standalone="yes"表示XML处理器必须仅使用DTD进行验证。

相反,将文档声明为独立实际上会强制非验证处理器解析它通常必须忽略的内部声明(即在忽略的参数实体引用之后的声明)。非验证处理器仍必须使用内部DTD中的信息来提供默认属性值和规范化标记化属性,因为这与验证无关。


3
最佳答案 - Mike

10
标记声明可能会影响从XML处理器传递到应用程序的文档内容,例如属性默认值和实体声明。独立文档声明可以作为XML声明的组成部分出现,指示是否存在这样的声明,这些声明出现在文档实体外部或参数实体中。【定义:外部标记声明被定义为出现在外部子集或参数实体(外部或内部,后者被包括在内,因为非验证处理器不需要读取它们)中的标记声明。】

http://www.w3.org/TR/xml/#sec-rmd


6
我给它投了反对票,因为这应该用通俗易懂的方式来表达,让普通人听得懂,而不仅仅是中等智商的人。 - Andrea Silvestri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接