我正在使用 PHP 来解析 Wordpress 提供给我的 HTML。
这是一个帖子的 PHP 返回我的 Wordpress:
<p>Test</p>
<p>
<img class="alignnone size-thumbnail wp-image-39" src="img.png"/>
</p>
<p>Ok.</p>
这是我的解析函数(有调试):
function get_parsed_blog_post()
{
$html = ob_wp_content(false);
print_r(htmlspecialchars($html));
echo '<hr/><hr/><hr/>';
$parse = new DOMDocument();
$parse->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXpath($parse);
$ps = $xpath->query('//p');
foreach ($ps as $p)
{
$imgs = $p->getElementsByTagName('img');
print($imgs->length);
echo '<br/>';
if ($imgs->length > 0)
{
$p->setAttribute('class', 'image-content');
foreach ($imgs as $img)
{
$img->removeAttribute('class');
}
}
}
$htmlFinal = $parse->saveHTML();
print_r(htmlspecialchars($htmlFinal));
echo '<hr/><hr/><hr/>';
return $htmlFinal;
}
此代码的目的是删除 Wordpress 添加到 <img>
的类s,并设置任何 <p>
包含图像的类 image-content
.
这会返回:
1
1
0
<p class="image-content">Test
<p class="image-content">
<img src="img.png">
</p>
<p>Ok.</p></p>
不知何故,它包装了第一次出现的 <p>
围绕我整个解析的帖子,导致第一个 <p>
拥有 image-content
错误地应用了类。为什么会这样?我该如何阻止它?
最佳答案
方法一
至于完全使用您的代码,我做了一些更改以使其正常工作。
如果你要打印出每个$p
您将能够看到第一个元素将包含您所有的 HTML。最简单的解决方案是添加一个空白 <p>
在你的 HTML 之前并在 foreach
时跳过它.
function get_parsed_blog_post()
{
$page_content_html = ob_wp_content(false);
$html = "<p></p>".$page_content_html;
print_r(htmlspecialchars($html));
echo '<hr/><hr/><hr/>';
$parse = new DOMDocument();
$parse->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXpath($parse);
$ps = $xpath->query('//p');
$i = 0;
foreach ($ps as $p)
{
if($i != 0) {
$imgs = $p->getElementsByTagName('img');
print($imgs->length);
echo '<br/>';
if ($imgs->length > 0)
{
$p->setAttribute('class', 'image-content');
foreach ($imgs as $img)
{
$img->removeAttribute('class');
}
}
}
$i++;
}
$htmlFinal = $parse->saveHTML();
print_r(htmlspecialchars($htmlFinal));
echo '<hr/><hr/><hr/>';
return $htmlFinal;
}
Total execution time in seconds: 0.00034999847412109
方法二
问题是由 LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
引起的(这也是第一个 <p>
作为父级),但是您可以在没有这个的情况下删除文档标签。所以,你可以在这里做:
function get_parsed_blog_post()
{
$page_content_html = ob_wp_content(false);
$doc = new DOMDocument();
$doc->loadHTML($page_content_html);
foreach($doc->getElementsByTagName('p') as $paragraph) {
$imgs = $paragraph->getElementsByTagName('img');
if ($imgs->length > 0)
{
$paragraph->setAttribute('class', 'image-content');
foreach ($imgs as $img)
{
$img->removeAttribute('class');
}
}
}
/* REMOVING DOCTYPE, HTML AND BODY TAGS */
// Removing DOCTYPE
$doc->removeChild($doc->doctype);
// Removing HTML tag
$doc->replaceChild($doc->firstChild->firstChild, $doc->firstChild);
// Removing Body Tag
$html = $doc->getElementsByTagName("body")->item(0);
$fragment = $doc->createDocumentFragment();
while ($html->childNodes->length > 0) {
$fragment->appendChild($html->childNodes->item(0));
}
$html->parentNode->replaceChild($fragment, $html);
$htmlFinal = $doc->saveHTML();
print_r(htmlspecialchars($htmlFinal));
echo '<hr/><hr/><hr/>';
return $htmlFinal;
}
Total execution time in seconds: 0.00026822090148926
关于php - 首先 getElementsByTagName() 返回 HTML 中的所有元素(奇怪的行为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30949944/