Search code examples
phpdomdocument

appendXML stripping out img element


I need to insert an image with a div element in the middle of an article. The page is generated using PHP from a CRM. I have a routine to count the characters for all the paragraph tags, and insert the HTML after the paragraph that has the 120th character. I am using appendXML and it works, until I try to insert an image element.

When I put the <img> element in, it is stripped out. I understand it is looking for XML, however, I am closing the <img> tag which I understood would help.

Is there a way to use appendXML and not strip out the img elements?

$mcustomHTML = "<div style="position:relative; overflow:hidden;"><a href="https://example.com/code=123456"><img src="https://s3.amazonaws.com/a.example.com/image.png" alt="No image" /></img></a></div>";

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="utf-8" ?>' . $content);        

// read all <p> tags and count the text until reach character 120        
// then add the custom html into current node
$pTags = $doc->getElementsByTagName('p');
foreach($pTags as $tag) {
    $characterCounter += strlen($tag->nodeValue);
    if($characterCounter > 120) {
        // this is the desired node, so put html code here
        $template = $doc->createDocumentFragment();
        $template->appendXML($mcustomHTML);
        $tag->appendChild($template);
        break;
    }
}
return $doc->saveHTML();

Solution

  • This should work for you. It uses a temporary DOM document to convert the HTML string that you have into something workable. Then we import the contents of the temporary document into the main one. Once it's imported we can simply append it like any other node.

    <?php
    $mcustomHTML = '<div style="position:relative; overflow:hidden;"><a href="https://example.com/code=123456"><img src="https://s3.amazonaws.com/a.example.com/image.png" alt="No image" /></a></div>';
    $customDoc = new DOMDocument();
    $customDoc->loadHTML($mcustomHTML, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    
    $doc = new DOMDocument();
    $doc->loadHTML($content);
    
    $customImport = $doc->importNode($customDoc->documentElement, true);
    
    // read all <p> tags and count the text until reach character 120        
    // then add the custom html into current node
    $pTags = $doc->getElementsByTagName('p');
    foreach($pTags as $tag) {
        $characterCounter += strlen($tag->nodeValue);
        if($characterCounter > 120) {
            // this is the desired node, so put html code here
            $tag->appendChild($customImport);
            break;
        }
    }
    return $doc->saveHTML();