每当我们通过数据库或类似来源的某些编辑来获取一些用户输入的内容时,我们可能会检索仅包含开始标记但没有关闭的部分.
这可能会妨碍网站的当前布局.
是否有客户端或服务器端的方法来解决这个问题?
KJS*_*KJS 24
找到了一个很好的答案:
使用PHP 5并使用DOMDocument对象的loadHTML()方法.这自动解析格式错误的HTML,随后调用saveXML()将输出有效的HTML.DOM函数可以在这里找到:
用法:
$doc = new DOMDocument();
$doc->loadHTML($yourText);
$yourText = $doc->saveHTML();
Run Code Online (Sandbox Code Playgroud)
kam*_*mal 15
我有解决方案的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
?>
Run Code Online (Sandbox Code Playgroud)
你可以使用这个功能
<?php echo closetags("your content <p>test test"); ?>
Run Code Online (Sandbox Code Playgroud)
对于HTML片段,并且根据KJS的答案,当片段有一个根元素时,我已成功完成以下操作:
$dom = new DOMDocument();
$dom->loadHTML($string);
$body = $dom->documentElement->firstChild->firstChild;
$string = $dom->saveHTML($body);
Run Code Online (Sandbox Code Playgroud)
如果没有根元素,这是可能的(但似乎只包含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);
}
Run Code Online (Sandbox Code Playgroud)
或者更好,从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();
Run Code Online (Sandbox Code Playgroud)
除了像Tidy这样的服务器端工具,您还可以使用用户的浏览器为您进行一些清理.其中一个非常棒的事情innerHTML是,它将对动态内容应用与HTML页面相同的即时修复.这段代码工作得很好(有两个警告),实际上没有任何内容写入页面:
var divTemp = document.createElement('div');
divTemp.innerHTML = '<p id="myPara">these <i>tags aren\'t <strong> closed';
console.log(divTemp.innerHTML);
Run Code Online (Sandbox Code Playgroud)
警告:
不同的浏览器将返回不同的字符串.这不是很糟糕,除了在IE的情况下,它将返回大写标签并将从标签属性中删除引号,这将不会通过验证.这里的解决方案是在服务器端进行一些简单的清理.但至少文档将是正确结构化的XML.
我怀疑你可能不得不在读取innerHTML之前延迟 - 给浏览器一个消化字符串的机会 - 或者你冒险回到确切的内容.我只是尝试了IE8,它看起来像字符串立即解析,但我对IE6不太确定.最好在延迟后读取innerHTML(或将其抛入setTimeout()以强制它到队列的末尾).
我建议你接受@ Gordon的建议并使用Tidy,如果你有权访问它(它实现的工作量较少)并且失败了,请使用innerHTML并在PHP中编写自己的整洁函数.
虽然这不是你的问题的一部分,因为这是一个CMS,考虑使用YUI 2富文本编辑器这样的东西.它实现起来相当容易,有些容易定制,大多数用户都非常熟悉这个界面,并且它会发出完全有效的代码.还有其他几个现成的富文本编辑器,但YUI拥有最好的许可证,是我见过的最强大的.
| 归档时间: |
|
| 查看次数: |
29482 次 |
| 最近记录: |