为什么PHP DOM不包含自闭标记的斜杠?

时间:2010-06-29 22:27:42

标签: php dom

我一直在使用PHP的DOM来加载html模板,修改它并输出它。最近我发现自闭(空)标签不包括斜线,即使模板文件也没有。

e.g。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"`"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
</body>
</html>

变为:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
</body>
</html>

这是错误或设置,还是doctype问题?

3 个答案:

答案 0 :(得分:20)

DOMDocument->saveHTML()将您的XML DOM信息集作为旧式HTML而不是XML写出来。您不应将saveHTML()与XHTML doctype一起使用,因为它的输出将不是格式良好的XML。

如果您使用saveXML(),您将获得正确的XHTML。如果您为其提供Content-Type: application/xhtml+xml标头,则可以将此XML输出提供给符合标准的浏览器。但不幸的是,IE6-8将无法阅读,因为它们仍然只能处理text/html媒体类型下的旧式HTML。

通常的折衷解决方案是提供text/html并使用XHTML 1.0规范附录C中概述的“HTML兼容XHTML”。但遗憾的是,没有PHP DOMDocument->saveXHTML()方法为此生成正确的输出。

您可以采取一些措施来说服saveXML()为某些常见情况生成与HTML兼容的输出。主要的一点是,您必须确保只有HTML4定义的具有EMPTY内容模型(<img><br>等)的元素实际上具有空内容,从而导致自我关闭要使用的语法(<img/>)。其他元素不能使用自我关闭语法,所以如果它们是空的,你应该在它们的文本内容中放置一个空格来阻止它们:

<script src="x.js"/>           <-- no good, confuses HTML parser and breaks page
<script src="x.js"> </script>  <-- fine

要注意的另一个是处理内联<script><style>元素,这些元素是XHTML中的常规元素,但是特殊CDATA - HTML中的内容元素。需要进行一些/*<![CDATA[*/.../*]]>*/换行才能使其中的任何<&个字符的行为大致一致,但请注意,您仍需要避开]]></序列。

如果你想真正做到这一点,你必须编写自己的HTML兼容的XHTML序列化程序。长期可能是一个更好的选择。但对于小的简单情况,黑客输入以使其不包含任何与XML不兼容的XML序列化程序的另一端可能是快速解决方案。

显然,或者只是简单地使用旧式的非XML HTML。

答案 1 :(得分:2)

doctype问题,因为它是text / html不需要结束斜杠,如果它是xhtml doc,你只需要关闭斜杠

注意到你已经更新了添加doctype,但PHP dom也会查看你在那里得到的元标记,而content =“text / html; charset = utf-8”显然不是基于XML的,它只是text / html:)

除此之外:DOM api还从那里拿起了字符集

答案 2 :(得分:-1)

这是一个老问题,但是......
正如其他人所说,PHP的DOM还有很多不足之处...... 这是一个关闭&#34;无效&#34;标签如果你愿意

$voidTags = array('area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr');
$regEx = '#<('.implode('|', $voidTags).')(\b[^>]*)>#';
$html = preg_replace($regEx, '<\\1\\2 />', $html);