PHP DOM 函数添加一个额外的 <p> <html> 和一个 <body> 标签
PHP DOM function adding an extra <p> <html> and a <body> tags
我使用以下函数向桌面和移动用户显示不同的图像,具体取决于他们的设备。
我的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>
我的挑战:
此函数正在向我的输出添加一个 <p>
标签以及额外的 <html><body>
标签。
我的输出图像
我的输出源码
<!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>
我的输出源代码图片
我的问题:
我怎样才能避免这个 <p>
<html>
和 <body>
标签?
已更新
根据@Aknosis 关于 <br/>
标签的建议更新。
您输出的内容是通过 DOMDocument 的 saveHTML 方法生成的:
$content = $dom->saveHTML($root);
您在此处引用根节点,即 documentElement,它是您不想输出的 <html>
元素的父元素。所以选择正确的元素输出,例如该文档的正文。
$body = $doc->getElementsByTagName('body')->item(0);
$content = implode(
"",
array_map([$doc, 'saveHTML'], iterator_to_array($body->childNodes))
);
echo $content;
在你的情况下,我认为你取第一个 <p>
元素而不是 <body>
元素。
对于某些相关案例,可能需要采用不同的方法,现场还有针对该主题的其他问答 material:
- How to get innerHTML of DOMNode?
- How to saveHTML of DOMDocument without HTML wrapper?
似乎 DOMDocument
总是需要一个根标签,所以如果您放置没有任何父 HTML 标签的原始文本,DOMDocument
将隐式添加它(所以 some text
变成 <p>some text</p>
)。我能想到的最好的方法是显式添加根标签并将它们从 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());
我使用以下函数向桌面和移动用户显示不同的图像,具体取决于他们的设备。
我的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>
我的挑战:
此函数正在向我的输出添加一个 <p>
标签以及额外的 <html><body>
标签。
我的输出图像
我的输出源码
<!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>
我的输出源代码图片
我的问题:
我怎样才能避免这个 <p>
<html>
和 <body>
标签?
已更新
根据@Aknosis 关于 <br/>
标签的建议更新。
您输出的内容是通过 DOMDocument 的 saveHTML 方法生成的:
$content = $dom->saveHTML($root);
您在此处引用根节点,即 documentElement,它是您不想输出的 <html>
元素的父元素。所以选择正确的元素输出,例如该文档的正文。
$body = $doc->getElementsByTagName('body')->item(0);
$content = implode(
"",
array_map([$doc, 'saveHTML'], iterator_to_array($body->childNodes))
);
echo $content;
在你的情况下,我认为你取第一个 <p>
元素而不是 <body>
元素。
对于某些相关案例,可能需要采用不同的方法,现场还有针对该主题的其他问答 material:
- How to get innerHTML of DOMNode?
- How to saveHTML of DOMDocument without HTML wrapper?
似乎 DOMDocument
总是需要一个根标签,所以如果您放置没有任何父 HTML 标签的原始文本,DOMDocument
将隐式添加它(所以 some text
变成 <p>some text</p>
)。我能想到的最好的方法是显式添加根标签并将它们从 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());