我在PHP中有一个脚本,它从HTML文件中删除空段落。空段落是那些没有textContent的<p></p>
元素。
包含空段落的HTML文件:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!--
This page is used with remove_empty_paragraphs.php script.
This page contains empty paragraphs. The script removes the empty paragraphs and
writes a new HTML file.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<p>This is a paragraph.</p>
<!-- Below is an empty paragraph. -->
<p><span></span></p>
<p>This is another paragraph.</p>
<!-- Below is another empty paragraph. -->
<p class=MsoNormal><b></b></p>
<p style=''></p>
<p>
<span lang=EN-US style='font-size:5.0pt;color:navy;mso-ansi-language:EN-`US'></span>
</p>
</body>
</html>
首次尝试:
$html = new DOMDocument("1.0", "UTF-8");
$html->loadHTMLFile("HTML File with Empty Paragraphs.html");
$pars = $html->getElementsByTagName("p");
/* removeChild foreach-loop */
foreach ($pars as $par) {
if ($par->textContent == "") {
$par->parentNode->removeChild($par);
}
}
$html->saveHTMLFile("HTML File WithOut Empty Paragraphs.html");
成功:
但未能到:
所以我在removeChild foreach-loop之前插入了removeStyleAttribute foreach-loop。 (我不介意删除非空段落的样式属性。)
第二次尝试:
$html = new DOMDocument("1.0", "UTF-8");
$html->loadHTMLFile("HTML File with Empty Paragraphs.html");
$pars = $html->getElementsByTagName("p");
/* removeStyleAttribute foreach-loop */
foreach ($pars as $par) {
if ($par->hasAttribute("style")) {
$par->removeAttribute("style");
}
}
/* removeChild foreach-loop */
foreach ($pars as $par) {
if ($par->textContent == "") {
$par->parentNode->removeChild($par);
}
}
$html->saveHTMLFile("HTML File WithOut Empty Paragraphs.html");
成功:
但失败了!来:
所以我必须有两个removeChild foreach-loops,一个接一个。
第三次尝试:
$html = new DOMDocument("1.0", "UTF-8");
$html->loadHTMLFile("HTML File with Empty Paragraphs.html");
$pars = $html->getElementsByTagName("p");
/* removeStyleAttribute foreach-loop */
foreach ($pars as $par) {
if ($par->hasAttribute("style")) {
$par->removeAttribute("style");
}
}
/* First removeChild foreach-loop */
foreach ($pars as $par) {
if ($par->textContent == "") {
$par->parentNode->removeChild($par);
}
}
/* Second removeChild foreach-loop, identical to the first removeChild foreach-loop */
foreach ($pars as $par) {
if ($par->textContent == "") {
$par->parentNode->removeChild($par);
}
}
$html->saveHTMLFile("HTML File WithOut Empty Paragraphs.html");
这完美无缺!,但有两个相同的循环,一个接着一个是奇怪的。
我也尝试过只使用一个循环。
第四次尝试:
$html = new DOMDocument("1.0", "UTF-8");
$html->loadHTMLFile("HTML File with Empty Paragraphs.html");
$pars = $html->getElementsByTagName("p");
foreach ($pars as $par) {
if ($par->textContent == "") {
if ($par->hasAttribute("style")){
$par->removeAttribute("style");
}
$par->parentNode->removeChild($par);
}
}
$html->saveHTMLFile("HTML File WithOut Empty Paragraphs.html");
成功:
但未能到:
答案 0 :(得分:1)
getElementsByTagName返回的列表是动态的:从文档中删除节点也会从列表中删除它们。由于foreach不知道列表发生了变化,因此它很乐意转移到下一个项目 - 实际上是两个项目,因为DOMNodeList已重新排列。一些&lt; p&gt;标签只是简单地跳过了。
解决方案:使用for循环(使用$ pars-&gt; item(X)和$ pars-&gt; length)而不是foreach,但仅在节点未删除时才递增。 (或者如果删除了一个,则总是递增和回溯。)
单独地:最后一个&lt; p&gt; (由于&lt; span&gt;周围的空格,因此未删除大的&lt; span&gt;)。使用trim()来摆脱它。
另请参阅http://forums.devnetwork.net/viewtopic.php?f=1&t=121114&p=623974中的回复。
答案 1 :(得分:0)
像Tomalak说的那样可能与空白有关。 尝试禁用“preserveWhiteSpace”:
$html->preserveWhiteSpace = false
嗯,我是新来的,如何将我的答案作为评论而非答案发送?