将 <img> 元素包装在 <div> 中,但允许 <a> 标签
Wrap <img> elements in <div> but allow for <a> tags
我有一个函数可以使用 DOMDocument 扫描字符串中的 img
标签并将它们包装在 div
中。
$str = 'string containing HTML';
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$tags = $doc->getElementsByTagName('img');
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
return $str;
但是,当 img
包含在 a
标签中时,a
标签将被移除,并且 'replaced' 包含 div
。如何保留 a
标签?
目前,
<a href="http://google.com"><img src="srctoimg"/></a>
结果;
<div><img src="srctoimg"/></div>
而不是;
<div><a href="http://google.com"><img src="srctoimg"/></a></div>
是否有 'wildcard' 我可以将第二个参数传递给 insertBefore()
或者我该如何实现?
使用 if
子句可能是最简单的:
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$x = $tag->parentNode;
// Parent node is not 'a': insert before <img>
if($tag->parentNode->tag != 'a') {
$tag->parentNode->insertBefore($div, $tag);
}
// Parent node is 'a': insert before <a>
else{
$tag->parentNode->parentNode->insertBefore($div, $tag);
}
$div->appendChild($tag);
}
在你的 foreach 中尝试这个
$parent = $tag->parentNode;
if( $parent->tagName == 'a' )
{
$parent->parentNode->insertBefore($div, $parent);
$div->appendChild($parent);
}
else
{
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
您可以使用 XPath 查询来完成此操作。
'//*[img/parent::a or (self::img and not(parent::a))]'
这将为具有 a
父级的任何 img
标签以及任何 image 标签本身获取 父级 对于没有直接 a
父级的任何 img
标签。
这样您就不必更改循环中的代码。
$str = <<<EOS
<html>
<body>
Image with link:
<a href="http://google.com">
<img src="srctoimg"/>
</a>
Image without link:
<img src="srctoimg"/>
</body>
</html>
EOS;
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($doc);
$tags = $xpath->query(
'//*[img/parent::a or (self::img and not(parent::a))]'
);
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
echo $doc->saveHTML();
输出(为清楚起见缩进):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
Image with link:
<div>
<a href="http://google.com">
<img src="srctoimg">
</a>
</div>
Image without link:
<div>
<img src="srctoimg">
</div>
</body>
</html>
使用 xpath
$str = 'string containing HTML';
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($doc);
$tags0 = $xpath->query('//a/img'); // get all <img> in <a> tag
$tags1 = $xpath->query('//img[not(parent::a)]'); // get all <img> except those with parent <a> tag
$tags = array_merge($tags0,$tags1); // merge the 2 arrays
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
return $str;
您好,我使用 jquery 提供此解决方案。我知道你在 php.
中问过这个问题
<a href="http://google.com"><img src="srctoimg"/></a>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
$('a').replaceWith(function(){
return $('<div/>', {
html: this.innerHTML
})
})
</script>
我有一个函数可以使用 DOMDocument 扫描字符串中的 img
标签并将它们包装在 div
中。
$str = 'string containing HTML';
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$tags = $doc->getElementsByTagName('img');
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
return $str;
但是,当 img
包含在 a
标签中时,a
标签将被移除,并且 'replaced' 包含 div
。如何保留 a
标签?
目前,
<a href="http://google.com"><img src="srctoimg"/></a>
结果;
<div><img src="srctoimg"/></div>
而不是;
<div><a href="http://google.com"><img src="srctoimg"/></a></div>
是否有 'wildcard' 我可以将第二个参数传递给 insertBefore()
或者我该如何实现?
使用 if
子句可能是最简单的:
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$x = $tag->parentNode;
// Parent node is not 'a': insert before <img>
if($tag->parentNode->tag != 'a') {
$tag->parentNode->insertBefore($div, $tag);
}
// Parent node is 'a': insert before <a>
else{
$tag->parentNode->parentNode->insertBefore($div, $tag);
}
$div->appendChild($tag);
}
在你的 foreach 中尝试这个
$parent = $tag->parentNode;
if( $parent->tagName == 'a' )
{
$parent->parentNode->insertBefore($div, $parent);
$div->appendChild($parent);
}
else
{
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
您可以使用 XPath 查询来完成此操作。
'//*[img/parent::a or (self::img and not(parent::a))]'
这将为具有 a
父级的任何 img
标签以及任何 image 标签本身获取 父级 对于没有直接 a
父级的任何 img
标签。
这样您就不必更改循环中的代码。
$str = <<<EOS
<html>
<body>
Image with link:
<a href="http://google.com">
<img src="srctoimg"/>
</a>
Image without link:
<img src="srctoimg"/>
</body>
</html>
EOS;
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($doc);
$tags = $xpath->query(
'//*[img/parent::a or (self::img and not(parent::a))]'
);
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
echo $doc->saveHTML();
输出(为清楚起见缩进):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
Image with link:
<div>
<a href="http://google.com">
<img src="srctoimg">
</a>
</div>
Image without link:
<div>
<img src="srctoimg">
</div>
</body>
</html>
使用 xpath
$str = 'string containing HTML';
$doc = new DOMDocument();
$doc->loadHtml(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($doc);
$tags0 = $xpath->query('//a/img'); // get all <img> in <a> tag
$tags1 = $xpath->query('//img[not(parent::a)]'); // get all <img> except those with parent <a> tag
$tags = array_merge($tags0,$tags1); // merge the 2 arrays
foreach ($tags as $tag) {
$div = $doc->createElement('div');
$tag->parentNode->insertBefore($div, $tag);
$div->appendChild($tag);
}
return $str;
您好,我使用 jquery 提供此解决方案。我知道你在 php.
中问过这个问题<a href="http://google.com"><img src="srctoimg"/></a>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
$('a').replaceWith(function(){
return $('<div/>', {
html: this.innerHTML
})
})
</script>