在<div>中换行<img/>个元素但允许<a> tags</a> </div>

时间:2015-03-27 14:31:04

标签: php dom

我有一个函数,使用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标记将被移除,并被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>

是否有'通配符'我可以将第二个参数传递给insertBefore()或者我该如何实现?

5 个答案:

答案 0 :(得分:4)

您可以使用XPath查询执行此操作。

'//*[img/parent::a or (self::img and not(parent::a))]'

对于任何具有img父级的a标记,以及任何图像标记本身,这将获得父级 {1}}标签没有立即img父。

这样您就不必更改循环中的代码。

a

输出(为清晰起见缩进):

$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();

答案 1 :(得分:2)

在你的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);
}

答案 2 :(得分:1)

使用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);
}

答案 3 :(得分:1)

使用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;

答案 4 :(得分:0)

您好我使用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>