在PHP中处理HTML dom

时间:2013-10-15 13:09:20

标签: php html5 dom

有办法做到这一点吗?我想用另一个元素替换一个元素但不知何故在PHP中是不可能的。得到了以下代码($ content在我的实际代码中是有效的html5,但是为了缩短代码,它还是用了一些东西。):

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

如果我将<img class="fullsize" src="/slide-01.jpg" />替换为<img class="fullsize" src="/slide-01.jpg">,则内容标记将替换为空字符串。尽管img没有关闭标签是完全有效的html,但它不起作用,因为PHP似乎只支持xml。我见过的所有示例代码都使用appendXML从字符串创建documentFragment,但没有HTML等价物。

有没有办法做到这一点,所以它不会因有效的HTML但无效的XML而失败?

1 个答案:

答案 0 :(得分:2)

DOMDocumentFragment::appendXML indead在我的版本中需要 XML (5.4.20,libxml2版本2.8.0)。您主要有两个选择:

  1. 为函数提供有效的XML(如<img />
  2. 这样的自闭标签
  3. 按照手册的建议“走很远的路”:
  4.   

    如果你想坚持标准,你将不得不创建一个带有虚拟根的临时DOMDocument,然后循环遍历XML数据根的子节点以附加它们。

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