修复未关闭的 HTML 标签
Posted
技术标签:
【中文标题】修复未关闭的 HTML 标签【英文标题】:Fixing unclosed HTML tags 【发布时间】:2012-01-19 23:39:57 【问题描述】:我正在处理一些博客布局,我需要为每篇文章(比如最近的 15 篇)创建一个摘要以显示在主页上。现在我使用的内容已经被 Textile 库格式化为 html 标签。现在,如果我使用 substr 获取帖子的第 500 个字符,我面临的主要问题是如何关闭未关闭的标签。
例如
<div>.......................</div>
<div>...........
<p>............</p>
<p>...........| 500 chars
</p>
<div>
我得到的是两个未闭合的标签
和
, p 不会造成太大的麻烦,但 div 只是弄乱了整个页面布局。那么有什么建议如何跟踪开始标签并手动关闭它们吗?【问题讨论】:
将开始标签推入堆栈,并弹出关闭的标签。考虑自闭合标签。当您消耗了足够多的文本字符后,将剩余的标签序列化为结束标签,后进先出。 有类似的讨论与使用 php here 进行 DOM 操作有关。 是的@alex 我想到了,尝试实现它有什么我可以效仿的例子吗?<p>
标签不需要关闭,除非在 XHTML 中。我们假设您使用的是 XHTML 吗?
不,我正在使用 html。正如我所说<p>
很好.. 它们是自动关闭的,但它的 div 标签导致主要布局问题
【参考方案1】:
您可以使用 DOMDocument 来执行此操作,但要注意字符串编码问题。此外,您必须使用完整的 HTML 文档,然后提取所需的组件。这是一个例子:
function make_excerpt ($rawHtml, $length = 500)
// append an ellipsis and "More" link
$content = substr($rawHtml, 0, $length)
. '… <a href="/link-to-somewhere">More ></a>';
// Detect the string encoding
$encoding = mb_detect_encoding($content);
// pass it to the DOMDocument constructor
$doc = new DOMDocument('', $encoding);
// Must include the content-type/charset meta tag with $encoding
// Bad HTML will trigger warnings, suppress those
@$doc->loadHTML('<html><head>'
. '<meta http-equiv="content-type" content="text/html; charset='
. $encoding . '"></head><body>' . trim($content) . '</body></html>');
// extract the components we want
$nodes = $doc->getElementsByTagName('body')->item(0)->childNodes;
$html = '';
$len = $nodes->length;
for ($i = 0; $i < $len; $i++)
$html .= $doc->saveHTML($nodes->item($i));
return $html;
$html = "<p>.......................</p>
<p>...........
<p>............</p>
<p>...........| 500 chars";
// output fixed html
echo make_excerpt($html, 500);
输出:
<p>.......................</p>
<p>...........
</p>
<p>............</p>
<p>...........| 500 chars… <a href="/link-to-somewhere">More ></a></p>
如果您使用 WordPress,您应该将 substr()
调用包装在对 wpautop
- wpautop(substr(...))
的调用中。您可能还希望测试传递给函数的 $rawHtml 的长度,如果不够长,则跳过附加“更多”链接。
【讨论】:
【参考方案2】:正如 ajreal 所说,DOMDocument 是一种解决方案。
例子:
$str = "
<html>
<head>
<title>test</title>
</head>
<body>
<p>error</i>
</body>
</html>
";
$doc = new DOMDocument();
@$doc->loadHTML($str);
echo $doc->saveHTML();
优点:原生包含在 PHP 中,与 PHP Tidy 相反。
【讨论】:
我很感激这是一个简单的答案,如果您正在处理一个简单的问题,并且不希望安装任何额外库的开销。就我而言,我让用户从电子邮件和 Word 中粘贴不完整的 HTML,这解决了它。 这正是我正在寻找的那种干净的答案。非常感谢。【参考方案3】:有很多方法可以使用:
-
使用适当的 HTML 解析器,例如 DOMDocument
使用PHP Tidy修复未关闭的标签
有些人会建议HTML Purifier
【讨论】:
不错,php tidy 真的很简单。 tidy 非常适合简单、快速和肮脏。呃,我的意思是清洁。 HTML Purifier 是一个野兽,非常适合复杂的规则集。以上是关于修复未关闭的 HTML 标签的主要内容,如果未能解决你的问题,请参考以下文章
springboot 1.5.2 thymeleaf 标签未关闭异常解决办法