由于 Alexander Taran 已针对此问题开放赏金以寻找明确的答案,我想我会查看 Razor source code on CodePlex 并提供一些详细信息。
首先,看看HtmlMarkupParser。它包含此参考数据:
//From http://dev.w3.org/html5/spec/Overview.html#elements-0
private ISet<string> _voidElements = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen",
"link", "meta", "param", "source", "track", "wbr"
};
这是通过HtmlMarkupParser.VoidElements 公开的,并且该属性的唯一用途是在HtmlMarkupParser.RestOfTag(...) 中。这是一个遍历一系列标记的解析器。相关的sn-p代码为:
if (VoidElements.Contains(tagName))
{
// Technically, void elements like "meta" are not allowed to have end tags. Just in case they do,
// we need to look ahead at the next set of tokens. If we see "<", "/", tag name, accept it and the ">" following it
// Place a bookmark
int bookmark = CurrentLocation.AbsoluteIndex;
// Skip whitespace
IEnumerable<HtmlSymbol> ws = ReadWhile(IsSpacingToken(includeNewLines: true));
// Open Angle
if (At(HtmlSymbolType.OpenAngle) && NextIs(HtmlSymbolType.Solidus))
{
HtmlSymbol openAngle = CurrentSymbol;
NextToken();
Assert(HtmlSymbolType.Solidus);
HtmlSymbol solidus = CurrentSymbol;
NextToken();
if (At(HtmlSymbolType.Text) && String.Equals(CurrentSymbol.Content, tagName, StringComparison.OrdinalIgnoreCase))
{
// Accept up to here
Accept(ws);
Accept(openAngle);
Accept(solidus);
AcceptAndMoveNext();
// Accept to '>', '<' or EOF
AcceptUntil(HtmlSymbolType.CloseAngle, HtmlSymbolType.OpenAngle);
// Accept the '>' if we saw it. And if we do see it, we're complete
return Optional(HtmlSymbolType.CloseAngle);
} // At(HtmlSymbolType.Text) && String.Equals(CurrentSymbol.Content, tagName, StringComparison.OrdinalIgnoreCase)
} // At(HtmlSymbolType.OpenAngle) && NextIs(HtmlSymbolType.Solidus)
// Go back to the bookmark and just finish this tag at the close angle
Context.Source.Position = bookmark;
NextToken();
}
这意味着将成功解析以下内容:
<link></link>
但是,前瞻是有限的,这意味着在结束标记之前看到的任何额外标记都会导致它失败:
<link>Some other tokens</link>
在这种情况下,可以扩展前瞻的范围。如果有人热衷,他们可以向 MVC 团队提供拉取请求。