当前位置: 首页 > 知识库问答 >
问题:

为什么散乱的结束标记会生成空段落?

饶谦
2023-03-14

显然,如果你有一个

<!DOCTYPE html>
<title></title>
<body>
</p>
</body>

即使结束标记周围存在任何文本,也没有任何文本是这个p元素的一部分——它将永远是空的,文本节点将永远独立存在:

<!DOCTYPE html>
<title></title>
<body>
some text</p>more text
</body>

如果body的上述内容被包装在

<!DOCTYPE html>
<title></title>
<body>
<p>some text</p>more text</p>
</body>

有趣的是,如果

<!DOCTYPE html>
<title></title>
</p>
<!DOCTYPE html>
<title></title>
</p><body>
<!DOCTYPE html>
<title></title>
</p></body>

我找不到任何引用规定一个没有相应开始标记的结束标记应该生成一个空元素,但考虑到它最初甚至不是有效的HTML,这也不应该让人感到惊讶。事实上,我只发现浏览器使用p元素(在某种程度上也使用br元素!)来实现这一点,但没有任何解释。

不过,它在使用传统HTML解析器和HTML5解析器的浏览器中是相当一致的,在怪癖模式和标准模式下都适用。因此,可以公平地推断,这是为了与早期规范或遗留行为的向后兼容性。

事实上,我确实在一个有点相关的问题的答案上找到了这条评论,这基本上证实了这一点:

原因是什么

但这并不能很好地解释为什么解析器处理显式


共有2个答案

宋瀚海
2023-03-14

HTML4 DTD声明段落元素的结束标记是可选的,但开始标记是必需的。

HTML4的SGML声明指出omittag是yes,这意味着开始标记可以被隐含。

结束标记遵循SGML规则:

结束标记关闭,回到匹配的开始标记,所有未关闭的中间开始标记省略结束标记

匿名块框是为文本节点等内联元素生成的,因此它们不需要由段落元素包装。

Mozilla bug数据库中有一个线程解释了这种行为:

  • Mozilla轻信地解析“半标记”,导致XSS安全问题

以下是Boris Zbarsky的相关评论:

事实上,据我所知,正确解析SGML/超文本标记语言需要我们这样做。也就是'

伊恩·希克森总结道:

这里工作的基本原则似乎是,标记是通过延迟任何结束标记来修复的,直到所有其他打开的元素都已关闭,并且没有尝试使DOM跟随HTMLDTD。

工具书类

>

HTML2.0规范

反对SGML的论据

标签汤:UAs如何处理

标签汤:如何Mac IE 5和Safari处理

解释Web SGML和HTML4.0

跨浏览器测试SGML短标记支持

Mozilla Bug 226495

短标签和Omittag

SGML系列文档语言的语法分析器:SGML、HTML、XML

XML-bobdc的一段简短、自以为是的历史。博客

凌博实
2023-03-14

HTML5中记录了它是必需的。看见http://w3c.github.io/html/syntax.html#the-在body insertion模式下,向下搜索标签名为“p”的结束标签,它显示:

如果打开元素的堆栈在按钮范围中没有与令牌具有相同标记名的元素,则这是一个解析错误;就像看到了标记名为“p”的开始标记一样,然后重新处理当前标记。

如果

为什么会这样,很难确定。通常情况下,这是因为过去某些浏览器将此视为bug,而网页开始依赖此行为,因此其他浏览器也必须实现此行为。

 类似资料:
  • 问题内容: 显然,如果元素中没有结束标签而没有匹配的开始标签,则大多数(如果不是全部)浏览器将在其位置生成一个空段: 即使end标记周围存在任何文本,也不会将其作为此元素的一部分-它将始终为空,并且文本节点将始终独立存在: 如果以上内容都包裹在和标记中,…我将让您猜测会发生什么: 有趣的是,如果标记之前没有或标记,则除IE9和更早版本之外的所有浏览器都 不会 生成空段落(另一方面,IE≤9始终会创

  • 问题内容: 我正在使用JAXB生成XML。但是JAXB会生成一个空的Tag来自我关闭。但是我的客户想要单独的空标签。我知道两者都是平等的,但他不同意我的看法。请任何人提出解决方案。谢谢。 样例代码: 实际输出: 预期产量: 编组代码: 我正在使用JDK 6.0 问题答案: 如果您已经从XSD生成了类,那么您还将生成ObjectFactory类。如果没有,请参考这里有关如何生成ObjectFacto

  • 问题内容: 抱歉,这听起来太简单了。我是Java的新手。 这是我用来检查的一些简单代码。当我运行它时,我无法停止它。我以为如果不写任何输入并按,就可以避免循环。 有人可以向我解释在这种情况下如何工作吗? 问题答案: 从System.in读取时,默认情况下是从键盘读取的,这是一个无限的输入流……它的行数与用户希望输入的行数相同。我认为发送EOF的控制序列可能会起作用,例如CTL-Z(或者是CTL-D

  • 问题内容: 在某些脚本中,我看到他们省略了为脚本编写结束标记的过程。为什么会这样,我也应该这样做吗? (我确定他们没有忘记它。) 问题答案: 好吧,省略结束标记只是避免在文件末尾出现空格和其他字符的一种解决方案。例如,在稍后尝试修改标头信息时,意外在结束标记后面添加的任何字符都会触发错误。 参照许多编码准则,删除结束标记是一种“好的做法”。

  • 问题内容: 我有一个有趣的现象与PHP结束标记。我有一个通过Ajax调用执行的php文件。在php文件中包含具有各种功能的php库文件。当包含此库时,php响应中包含一堆空行。当我从库中删除结束标签时,这停止了。谁能告诉我这里发生了什么? 问题答案: 这是有据可查的。从PHP手册: 文件末尾的PHP块的结束标记是可选的,在某些情况下,当使用include()或require()时,它会有所帮助,因

  • 问题内容: 我正在努力从以下代码中获取正确的输出: 游乐场片段 打印时,结构字段为空。我敢肯定某个地方有一个愚蠢的错误,但是我仍然对Go还是陌生的,而且我已经在这里呆了几个小时。请帮忙。 问题答案: 这已经出现了很多次了。问题在于只能对导出的字段进行封送处理。 通过以大写(大写)字母开头来导出结构域。 在Go Playground上尝试一下。 请注意,JSON文本包含带有小写字母文本的字段名称,但