由于 Alexander Taran 在此问题上展开了悬赏以寻找明确的答案,因此我想我会查看CodePlex 上的 Razor 源代码并提供一些详细信息。
首先,看一下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(...)
. 这是一个遍历一系列标记的解析器。相关的代码片段是:
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 团队提供拉取请求。