简体   繁体   中英

PHP: How to check if a <p> has a child node of <iframe> with DOMDocument?

How can I check if a p has a child node of iframe with DOMDocument ?

For instance,

<p><iframe ....></p>

I want to print this only,

<iframe ....>

While,

<p>bla bla bal</p>

then do nothing or just print whatever inside the p,

<p>bla bla bal</p>

Or,

<p>bla bla <b>bal</b></p>

then do nothing or just print whatever inside the p,

<p>bla bla <b>bal</b></p>

my php,

$dom = new DOMDocument;
$dom->loadHTML($item_html);

if($dom->getElementsByTagName('p')->length > 1 )
{
    ...
}
else // if it is only a single paragraph... then do what I want above...
{

    foreach ($dom->getElementsByTagName('p') as $node)
    {
        if ($node->hasChildNodes()) 
        {
           foreach( $dom->getElementsByTagName('iframe') as $iframe ) 
            {
               ... something
            }
        }
        else
        {
            ... 
        }
     }
}

is it possible?

You're trying to find all iframe elements that are the only childnodes of the p elements.

If found you want to replace their parent p element with them.

/** @var DOMElement $p */
foreach ($doc->getElementsByTagName('p') as $p) {
    if ($p->childNodes->length !== 1) {
        continue;
    }

    $child = $p->childNodes->item(0);

    if (! $child instanceof DOMElement) {
        continue;
    }

    if ($child->tagName !== 'iframe') {
        continue;
    }

    $p->parentNode->insertBefore($child, $p);
    $p->parentNode->removeChild($p);
}

This foreach loop just iterates over all p elements, ignores all that don't have a single child node that is not a DOMElement with the iframe tagname (note: always lowercase in the compare).

If one p element is found, then the inner iframe is moved before it and then the paragraph is removed.

Usage Example:

<?php
/**
 * @link http://stackoverflow.com/q/19021983/367456
 */

$html = '
<p><iframe src="...."></p>
<p>bla bla bal</p>
<p>bla bla <b>bal</b></p>
<p></p>
';

$doc = new DOMDocument();
$doc->loadHTML($html);

/** @var DOMElement[] $ps */
// $ps = $;

/** @var DOMElement $p */
foreach ($doc->getElementsByTagName('p') as $p) {
    if ($p->childNodes->length !== 1) {
        continue;
    }

    $child = $p->childNodes->item(0);

    if (!$child instanceof DOMElement) {
        continue;
    }

    if ($child->tagName !== 'iframe') {
        continue;
    }

    $p->parentNode->insertBefore($child, $p);
    $p->parentNode->removeChild($p);
}

// output
foreach ($doc->getElementsByTagName('body')->item(0)->childNodes as $child) {
    echo $doc->saveHTML($child);
}

Demo and Output:

<iframe src="...."></iframe>
<p>bla bla bal</p>
<p>bla bla <b>bal</b></p>
<p></p>

Hope this is helpful.

So do this:

    $dom = new DOMDocument;
    $dom->loadHTML($item_html);

    if($dom->getElementsByTagName('p')->length > 1 )
    {
        ...
    }
    else // if it is only a single paragraph... then do what I want above...
    {

        foreach ($dom->getElementsByTagName('p') as $node)
        {
            if ($node->hasChildNodes()) 
            {
                if($dom->getElementsByTagName('iframe')->length > 0 )
                  {
                  foreach( $dom->getElementsByTagName('iframe') as $iframe ) 
                   {
                      ... something
                   }
                }
            }
            else
            {
                ... 
            }
         }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM