【问题标题】:PHP DOM function adding an extra <p> <html> and a <body> tagsPHP DOM 函数添加一个额外的 <p> <html> 和一个 <body> 标签
【发布时间】:2018-03-09 07:11:42
【问题描述】:

我使用以下功能向桌面和移动用户显示不同的图像,具体取决于他们的设备。

我的 index.php 文件

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Testing Page</title>
</head>
<body>
<?php 
define("DEVICE", "desktop");
ob_start(); 
?>
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<?php echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' . '<br/>'?> 
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<img src="/desktop-img/blog-1.png" alt="blog-1">
<img src="/desktop-img/blog-2.png" alt="blog-2">
<img src="/desktop-img/blog-3.png" alt="blog-3">
</div>
<?php
// Assign bufferred content to a variable for further processing
$content = ob_get_clean();

// Device specific images
function selectPaths($tag){

    // If paths is wrapped in <pre> or <code> tags
    if($tag->nodeName=="pre" || $tag->nodeName=="code"){
        return;
    // If not wrapped witihn <pre> or <code> tags
    } elseif($tag->nodeName=="img"){
        // Replace device specific path
        $tag->attributes->getNamedItem("src")->nodeValue=str_replace('desktop-img', DEVICE . '-img',$tag->attributes->getNamedItem("src")->nodeValue);
    } elseif($tag->hasChildNodes()){
        foreach($tag->childNodes as $child){
            selectPaths($child);
        }
    }
}

function deviceImages($content){

    $dom=new DOMDocument;
    $dom->preserveWhiteSpace=true;
    libxml_use_internal_errors(true);
    $dom->loadHTML($content);
    libxml_clear_errors();
    $root=$dom->documentElement;
    selectPaths($root);
    $dom->formatOutput=false;
    //Assign to variable
    $content = $dom->saveHTML($root);
    return $content;
}
$content = deviceImages ($content);
?>
<div id='wrapper'>
    <?php echo $content; ?>
</div>
</body>
</html>

我的挑战:

这个函数在我的输出中添加一个&lt;p&gt;标签和额外的&lt;html&gt;&lt;body&gt;标签。

我的输出图像

我的输出源代码

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Testing Page</title>
</head>
<body>
<div id='wrapper'>
    <html><body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br></p>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<img src="/desktop-img/blog-1.png" alt="blog-1"><img src="/desktop-img/blog-2.png" alt="blog-2"><img src="/desktop-img/blog-3.png" alt="blog-3">
</div>
</body></html></div>
</body>
</html>

我的输出源代码图片

我的问题:

如何避免这种&lt;p&gt; &lt;html&gt; 和&lt;body&gt; 标签?

更新

根据@Aknosis 关于&lt;br/&gt; 标签的建议进行了更新。

【问题讨论】:

  • 我没有回答你的第一个问题,但它正在剥离 &lt;/br&gt; 标签,因为它们是无效的 HTML。它们应该是&lt;br/&gt; 标签。
  • @Aknosis 感谢您的建议。它奏效了。

标签: php html dom domdocument


【解决方案1】:

你输出的内容是通过 DOMDocument 的 saveHTML 方法生成的:

$content = $dom->saveHTML($root);

您在此处引用根节点,即 documentElement,它是您不想输出的 &lt;html&gt; 元素的父元素。所以选择正确的元素来输出,例如该文档的正文。

$body = $doc->getElementsByTagName('body')->item(0);

$content = implode(
    "",
    array_map([$doc, 'saveHTML'], iterator_to_array($body->childNodes))
);

echo $content;

在您的情况下,我认为您使用第一个 &lt;p&gt; 元素而不是 &lt;body&gt; 元素。

对于某些相关案例,可能需要采用不同的方法,现场还有针对该主题的其他问答材料:

【讨论】:

  • 并不是说我会为你付款,但这个网站是关于学习的,而不是让别人完成的事情。
  • 将$doc 替换为$dom,您为DOM 文档使用了不同的变量名称(或者我在示例中使用的变量名称与您的问题不同,这是我的错) .
  • 您使用的是哪个 PHP 版本?我在 PHP 7.1 上运行示例,可能是复制/粘贴错误?
  • 我的 PHP 版本是 5.6.31。我使用 Dreamweaver CS6 进行编码,它在 $content = implode( "", array_map([$dom, 'saveHTML'], iterator_to_array($body-&gt;childNodes))); 中显示语法错误,请检查我提到的,我不是编码专家。
  • 一些不同的语法可能对你有用:$content = ""; foreach($body-&gt;childNodes as $node) $content .= $dom-&gt;saveHTML($node);
【解决方案2】:

似乎DOMDocument 总是需要一个根标签,所以如果你放置没有任何父 HTML 标签的原始文本,DOMDocument 将隐式添加它(所以some text 变为&lt;p&gt;some text&lt;/p&gt;)。我能想到的最好的办法是显式添加根标签并将它们从saveHTML() 结果中删除:

$dom->loadHTML(
    '<html><body>' . $html . '</body></html>',
    LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED
);

// do your stuff

$result = str_replace(['<html><body>', '</body></html>'], '', $dom->saveHTML());

【讨论】:

    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2010-12-22
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多