每当我们从数据库或类似来源通过一些编辑获取一些用户输入的内容时,我们可能会检索仅包含开始标记但不包含结束标记的部分。
这可能会妨碍网站的当前布局。
是否有客户端或服务器端的方法来解决这个问题?
每当我们从数据库或类似来源通过一些编辑获取一些用户输入的内容时,我们可能会检索仅包含开始标记但不包含结束标记的部分。
这可能会妨碍网站的当前布局。
是否有客户端或服务器端的方法来解决这个问题?
找到了一个很好的答案:
使用 PHP 5 并使用 DOMDocument 对象的 loadHTML() 方法。这会自动解析格式错误的 HTML,随后对 saveXML() 的调用将输出有效的 HTML。DOM 函数可以在这里找到:
这个的用法:
$doc = new DOMDocument();
$doc->loadHTML($yourText);
$yourText = $doc->saveHTML();
我有 php 的解决方案
<?php
// close opened html tags
function closetags ( $html )
{
#put all opened tags into an array
preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result );
$openedtags = $result[1];
#put all closed tags into an array
preg_match_all ( "#</([a-z]+)>#iU", $html, $result );
$closedtags = $result[1];
$len_opened = count ( $openedtags );
# all tags are closed
if( count ( $closedtags ) == $len_opened )
{
return $html;
}
$openedtags = array_reverse ( $openedtags );
# close tags
for( $i = 0; $i < $len_opened; $i++ )
{
if ( !in_array ( $openedtags[$i], $closedtags ) )
{
$html .= "</" . $openedtags[$i] . ">";
}
else
{
unset ( $closedtags[array_search ( $openedtags[$i], $closedtags)] );
}
}
return $html;
}
// close opened html tags
?>
你可以像这样使用这个功能
<?php echo closetags("your content <p>test test"); ?>
您可以使用整洁:
Tidy 是 Tidy HTML 清理和修复实用程序的绑定,它允许您不仅清理和以其他方式操作 HTML 文档,还可以遍历文档树。
HTML Purifier 是一个用 PHP 编写的符合标准的 HTML 过滤器库。HTML Purifier 不仅会使用经过彻底审核、安全但允许的白名单删除所有恶意代码(也称为 XSS),还会确保您的文档符合标准,这只有在全面了解 W3C 规范的情况下才能实现。
对于 HTML 片段,并根据KJS 的回答,当片段具有一个根元素时,我已成功执行以下操作:
$dom = new DOMDocument();
$dom->loadHTML($string);
$body = $dom->documentElement->firstChild->firstChild;
$string = $dom->saveHTML($body);
如果没有根元素,这是可能的(但似乎只包装了 p 标签中的第一个文本子节点text <p>para</p> text):
$dom = new DOMDocument();
$dom->loadHTML($string);
$bodyChildNodes = $dom->documentElement->firstChild->childNodes;
$string = '';
foreach ($bodyChildNodes as $node){
$string .= $dom->saveHTML($node);
}
或者更好的是,从 PHP >= 5.4 和 libxml >= 2.7.8(2.7.7 for LIBXML_HTML_NOIMPLIED):
$dom = new DOMDocument();
// Load with no html/body tags and do not add a default dtd
$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$string = $dom->saveHTML();
除了像 Tidy 这样的服务器端工具,您还可以使用用户的浏览器为您做一些清理工作。真正伟大的事情之一innerHTML是它将对动态内容应用相同的即时修复,就像对 HTML 页面一样。这段代码运行良好(有两个警告),实际上没有任何内容写入页面:
var divTemp = document.createElement('div');
divTemp.innerHTML = '<p id="myPara">these <i>tags aren\'t <strong> closed';
console.log(divTemp.innerHTML);
警告:
不同的浏览器会返回不同的字符串。这还不错,除了在 IE 的情况下,它会返回大写的标签并从标签属性中去除引号,这将不会通过验证。这里的解决方案是在服务器端做一些简单的清理。但至少文档将是结构正确的 XML。
我怀疑您可能需要在阅读 innerHTML 之前延迟 - 让浏览器有机会消化该字符串 - 否则您可能会准确地取回放入的内容。我刚刚在 IE8 上尝试过,它看起来像字符串立即被解析,但我对 IE6 不太确定。最好在延迟后读取 innerHTML(或将其放入 setTimeout() 以强制它到队列的末尾)。
我建议你接受@Gordon 的建议并使用 Tidy,如果你可以访问它(它需要更少的工作来实现)并且失败了,使用 innerHTML 并在 PHP 中编写你自己的 tidy 函数。
尽管这不是您的问题的一部分,因为这是针对 CMS 的,但也可以考虑将YUI 2 Rich Text Editor用于此类内容。它相当容易实现,有点容易定制,大多数用户都非常熟悉该界面,并且它会输出完全有效的代码。还有其他几种现成的富文本编辑器,但 YUI 拥有最好的许可证,也是我见过的最强大的。