<?
$string = '
Some photos<br>
<span class="naslov_slike">photo_by_ile_IMG_1676-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1699-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1697-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1695-01</span><br />
';
$dom = new DOMDocument();
$dom->loadHTML($string);
$dom->preserveWhiteSpace = false;
$elements = $dom->getElementsByTagName('span');
$spans = array();
foreach($elements as $span) {
$spans[] = $span;
}
foreach($spans as $span) {
$span->parentNode->removeChild($span);
}
echo $dom->saveHTML();
?>
我正在使用此代码来解析字符串。当此函数返回string时,它有一些添加的标记:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>Some photos<br><br><br><br><br></p></body></html>
有没有办法避免这种情况并且返回干净的字符串?这个输入字符串就是例如,在使用中它可以是任何html字符串。
答案 0 :(得分:7)
我实际上在寻找相同的解决方案。我一直在使用innerHTML方法来执行此操作,但是当您执行loadHTML时,仍然会添加文本节点周围的<p>
。我没有办法绕过它而不使用另一个解析器,或者有一些隐藏的标志告诉它不要那样做。
此代码:
<?php
function innerHTML($node){
$doc = new DOMDocument();
foreach ($node->childNodes as $child)
$doc->appendChild($doc->importNode($child, true));
return $doc->saveHTML();
}
$string = '
Some photos<br>
<span class="naslov_slike">photo_by_ile_IMG_1676-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1699-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1697-01</span><br />
<span class="naslov_slike">photo_by_ile_IMG_1695-01</span><br />
';
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->loadHTML($string);
$elements = $dom->getElementsByTagName('span');
$spans = array();
foreach($elements as $span) {
$spans[] = $span;
}
foreach($spans as $span) {
$span->parentNode->removeChild($span);
}
echo innerHTML( $dom->documentElement->firstChild );
将输出:
<p>Some photos<br><br><br><br><br></p>
然而,当然这个解决方案并没有保持100%完整的标记,但它已经接近了。
答案 1 :(得分:4)
为什么不回答一个9岁的问题? PHP 5.4版本(在提出此问题3年后发布)向options
添加了DomDocument::loadHTML()
参数。有了它,您可以执行以下操作:
$dom = new DomDocument();
$dom->loadHTML($string, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
// do stuff
echo $dom->saveHTML();
我们传递两个常量:LIBXML_HTML_NODEFDTD
表示不添加文档类型定义,而LIBXML_HTML_NOIMPLIED
表示不添加隐含元素,例如<html>
和<body>
。
答案 2 :(得分:3)
使用loadHTML后,您可以这样做:
# loadHTML causes a !DOCTYPE tag to be added, so remove it:
$dom->removeChild($dom->firstChild);
# it also wraps the code in <html><body></body></html>, so remove that:
$dom->replaceChild($dom->firstChild->firstChild->firstChild, $dom->firstChild);
!DOCTYPE
标记将被删除,body
标记内的第一个标记将替换html
标记。
显然,只有当你对body
中的第一个标签感兴趣时才会这样做,就像我遇到这个问题时一样。但是这个例子可以用来复制body
内的所有内容,只需要一点努力。
编辑:嗯,没关系。我喜欢meder的解决方案。
答案 3 :(得分:1)
你总是可以使用正则表达式去除第一位:
echo preg_replace("/<!DOCTYPE [^>]+>/", "", $dom->saveHTML());
答案 4 :(得分:0)
从手册中: http://php.net/manual/en/domdocument.savehtml.php
$html_fragment = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
适合我。
答案 5 :(得分:-2)
我不确定其中任何一个是否真的有用,但您可以在构建DOMDocument
时尝试使用DOMImplementation::createDocument
- 第三个参数是您希望使用的DOCTYPE
。
此外,您可以尝试saveXML()
saveHTML()