简体   繁体   中英

Manipulate HTML dom in PHP

Is there a way to do this? I would like to replace one element with another but somehow it isn't possible in PHP. Got the following code (the $content is valid html5 in my real code but took off some stuff to make the code shorter.):

$content='<!DOCTYPE html>
<content></content>
</html>';

$with='<img class="fullsize" src="/slide-01.jpg" />';
function replaceCustom($content,$with) {
  @$document = DOMDocument::loadHTML($content);
  $source = $document->getElementsByTagName("content")->item(0);
  if(!$source){
    return $content;
  }
  $fragment = $document->createDocumentFragment();
  $document->validate();
  $fragment->appendXML($with);
  $source->parentNode->replaceChild($fragment, $source);

  $document->formatOutput = TRUE;


  $content = $document->saveHTML();
  return $content;
}
echo replaceCustom($content,$with);

If I replace the <img class="fullsize" src="/slide-01.jpg" /> with <img class="fullsize" src="/slide-01.jpg"> then the content tag gets replaced with an empty string. Even though the img without closing tag is perfectly valid html it won't work because PHP only seems to support xml. All example code I've seen make use of the appendXML to create a documentFragment from a string but there is no HTML equivalent.

Is there a way to do this so it won't fail with valid HTML but invalid XML?

DOMDocumentFragment::appendXML indead requires XML in my version (5.4.20, libxml2 Version 2.8.0). You have mainly 2 options:

  1. Provide valid XML to the function (so a self closing tag like <img /> .
  2. Go 'the long way around', as suggested by the manual:

If you want to stick to the standards, you will have to create a temporary DOMDocument with a dummy root and then loop through the child nodes of the root of your XML data to append them.

$tempDoc = new DOMDocument();
$tempDoc->loadHTML('<html><body>'.$with.'</body></html>');
$body = $tempDoc->getElementsByTagName('body')->item(0);
foreach($body->childNodes as $node){
   $newNode = $document->importNode($node, true);
   $source->parentNode->insertBefore($newNode,$source);
}
$source->parentNode->removeChild($source);

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