为什么';PHP DOM是否包含自动关闭标记上的斜杠?

为什么';PHP DOM是否包含自动关闭标记上的斜杠?,php,dom,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="t

我一直在使用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问题?

doctype问题,因为它是text/html。不需要结束斜杠,如果它是xhtml文档,则只需要结束斜杠

注意到您已经更新为添加doctype,但PHP dom也会查看您在其中的meta标记,content=“text/html;charset=utf-8”显然不是基于XML的,它只是text/html:)


旁白:DOM api还从中提取字符集

DOMDocument->saveHTML()
获取XML DOM信息集,并将其作为老式HTML而不是XML写入。您不应该将
saveHTML()
与XHTML doctype一起使用,因为它的输出不会是格式良好的XML

如果改用
saveXML()
,您将得到正确的XHTML。如果您给它一个
内容类型:application/xhtml+XML
头,那么可以将此XML输出提供给符合标准的浏览器。但不幸的是,IE6-8无法读取这些内容,因为它们仍然只能处理
text/HTML
媒体类型下的老式HTML

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


您可以做一些事情来说服
saveXML()
为一些常见情况生成与HTML兼容的输出。主要的一点是,您必须确保只有HTML4定义的元素具有
空的
内容模型(
这是一个老问题,但是…
正如其他人所说,PHP的DOM还有很多需要改进的地方……
如果你愿意,这里有一个正则表达式来关闭“void”标签

<script src="x.js"/>           <-- no good, confuses HTML parser and breaks page
<script src="x.js"> </script>  <-- fine
$voidTags=array('area'、'base'、'br'、'col'、'command'、'embed'、'hr'、'img'、'input'、'keygen'、'link'、'meta'、'param'、'source'、'track'、'wbr');
$regEx='#]*)>#;
$html=preg_replace($regEx,,$html);

您是否尝试添加doctype以查看结果?我一直在使用XHTML doctype,认为它不相关,因为我累了-\ux-我仍然不理解为什么人们使用XHTML doctype-尤其是当他们使用文本/html的内容类型使其站点在IE中正常工作时。。。对于99%的web,xhtml没有为HTML4.01提供任何优势,代价是必须不正确地实现它(即content type=text/html)。xhtml与XML工具链兼容,并且在XML工具方面进行了巨大的投资,可能对浏览器没有影响,但它确实对许多其他客户端和生成器产生了影响(特别是如果您将xslt等添加到混合中)感谢您的详细回复。我一直讨厌PHP的DOM,但这是棺材上的糖衣。我可以尝试一些简单的正则表达式预/后处理,用saveXML()更改输入/输出。这不是一个理想的解决方案。PHP的DOM支持HTML5吗?不惜一切代价避免正则表达式攻击输出HTML。(但我想说,不是吗?)编写XHTML序列化程序并没有那么糟糕(XML序列化比解析更容易);这会很慢,但是使用
DOMDocument
准备模板通常相当慢。至于HTML5,它将有效地与HTML4一样工作。PHP不知道新的HTML5元素,因此如果使用任何
空的
(例如
)你会得到一个无效的结束标记。哦,哇,这么说吧。你知道用PHP快速准备模板(HTML或XHTML)的方法吗?PHP是一种模板语言,不是吗?:-)好的,这不是一种没有问题的语言,特别是它不默认HTML编码输出的方式,但您至少可以编写一个快捷功能,每次保存Puting
echo htmlspecialchars
。PHP有几十种可供选择的模板系统,以满足不同的需求。要避免使用
保存XML
,请使用
$node->appendChild($dom->createTextNode(“”))。似乎存在一些问题。我修改了它,这对我很有用:
$regEx='#]+)>#g'
<script src="x.js"/>           <-- no good, confuses HTML parser and breaks page
<script src="x.js"> </script>  <-- fine
$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);