Php 如何获取DOMNode的innerHTML?

Php 如何获取DOMNode的innerHTML?,php,dom,innerhtml,Php,Dom,Innerhtml,在PHPDOM实现中,您使用什么函数获取给定DOMNode的innerHTML?有人能给出可靠的解决方案吗 当然,outerHTML也可以。此更新的变体包含: 例如: <?php $dom= new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->load($html_string); $domTables = $dom->ge

在PHPDOM实现中,您使用什么函数获取给定DOMNode的innerHTML?有人能给出可靠的解决方案吗

当然,outerHTML也可以。此更新的变体包含:


例如:

<?php 
$dom= new DOMDocument(); 
$dom->preserveWhiteSpace = false;
$dom->formatOutput       = true;
$dom->load($html_string); 

$domTables = $dom->getElementsByTagName("table"); 

// Iterate over DOMNodeList (Implements Traversable)
foreach ($domTables as $table) 
{ 
    echo DOMinnerHTML($table); 
} 
?> 

要返回元素的
html
,可以使用:


哈伊姆·埃夫吉答案的简化版本:

<?php

function innerHTML(\DOMElement $element)
{
    $doc = $element->ownerDocument;

    $html = '';

    foreach ($element->childNodes as $node) {
        $html .= $doc->saveHTML($node);
    }

    return $html;
}
以下是一个函数式编程风格的版本:


除了trincot的漂亮版本,它具有
array\u map
内爆
,但这次使用
array\u reduce

return array_reduce(
   iterator_to_array($node->childNodes),
   function ($carry, \DOMNode $child) {
        return $carry.$child->ownerDocument->saveHTML($child);
   }
);

我仍然不明白,为什么没有一个
reduce()
方法可以接受数组和迭代器。

这是另一个基于php.net上Drupella的方法,它对我的项目很有效。它通过创建一个新的
DOMDocument
,导入并附加目标节点,而不是显式迭代子节点,来定义
innerHTML()

InnerHTML 让我们定义这个辅助函数:

function innerHTML( \DOMNode $n, $include_target_tag = true ) {
  $doc = new \DOMDocument();
  $doc->appendChild( $doc->importNode( $n, true ) );
  $html = trim( $doc->saveHTML() );
  if ( $include_target_tag ) {
      return $html;
  }
  return preg_replace( '@^<' . $n->nodeName .'[^>]*>|</'. $n->nodeName .'>$@', '', $html );
}
函数innerHTML(\DOMNode$n,$include\u target\u tag=true){
$doc=new\DOMDocument();
$doc->appendChild($doc->importNode($n,true));
$html=trim($doc->saveHTML());
如果($include\u target\u tag){
返回$html;
}
返回preg_replace('@^]*>|$@',''$html);
}
我们可以通过第二个输入参数包含/排除外部目标标记

用法示例 这里,我们为“first”id属性给出的目标标记提取内部HTML:

$html = '<div id="first"><h1>Hello</h1></div><div id="second"><p>World!</p></div>';
$doc  = new \DOMDocument();
$doc->loadHTML( $html );
$node = $doc->getElementById( 'first' );

if ( $node instanceof \DOMNode ) {

    echo innerHTML( $node, true );
    // Output: <div id="first"><h1>Hello</h1></div>    

    echo innerHTML( $node, false );
    // Output: <h1>Hello</h1>
}
$html='你好World

",; $doc=new\DOMDocument(); $doc->loadHTML($html); $node=$doc->getElementById('first'); if($node instanceof\DOMNode){ echo innerHTML($node,true); //输出:您好 echo innerHTML($node,false); //输出:您好 }
实例:


旧的查询,但有一个内置的方法来实现。只需将目标节点传递到
DomDocument->saveHtml()

完整示例:

$html = '<div><p>ciao questa è una <b>prova</b>.</p></div>';
$dom = new DomDocument($html);
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$node = $xpath->query('.//div/*'); // with * you get inner html without surrounding div tag; without * you get inner html with surrounding div tag
$innerHtml = $dom->saveHtml($node);
var_dump($innerHtml);
$html=”ciao questaèuna prova.

; $dom=新的DomDocument($html); @$dom->loadHTML($html); $xpath=newdomxpath($dom); $node=$xpath->query('.//div/*');//使用*可以获得内部html,而不需要周围的div标记;没有*你会得到内部html和周围的div标签 $innerHtml=$dom->saveHtml($node); 变量转储($innerHtml);

输出:
谢谢。它很好用。不应该$dom->preserveWhiteSpace=false;是否在加载文档之前?@JohnM2:。其他注意事项:由于PHP5.3.6,您可以备用临时
DOMDocument
。还有人可能想用
ltrim
替换
trim
(甚至完全移除)保留一点空格,比如换行符。类似这样的函数应该添加到DomDocument类中。当我从
DomDocument::getElementById()
传递返回时,我必须更改函数声明,以期望使用
DOMElement
而不是
DOMNode
。以防绊倒其他人。C14N将尝试将HTML转换为有效的XML。例如,
将变成

这是一种肮脏的方式,可以转储元素的HTML,而不必使用saveHTML来输出HTML、head和body标记。警告:DOMDocument::saveHTML()希望参数1是给定对象的DOMNode
function innerHTML($node) {
    return implode(array_map([$node->ownerDocument,"saveHTML"], 
                             iterator_to_array($node->childNodes)));
}
return array_reduce(
   iterator_to_array($node->childNodes),
   function ($carry, \DOMNode $child) {
        return $carry.$child->ownerDocument->saveHTML($child);
   }
);
function innerHTML( \DOMNode $n, $include_target_tag = true ) {
  $doc = new \DOMDocument();
  $doc->appendChild( $doc->importNode( $n, true ) );
  $html = trim( $doc->saveHTML() );
  if ( $include_target_tag ) {
      return $html;
  }
  return preg_replace( '@^<' . $n->nodeName .'[^>]*>|</'. $n->nodeName .'>$@', '', $html );
}
$html = '<div id="first"><h1>Hello</h1></div><div id="second"><p>World!</p></div>';
$doc  = new \DOMDocument();
$doc->loadHTML( $html );
$node = $doc->getElementById( 'first' );

if ( $node instanceof \DOMNode ) {

    echo innerHTML( $node, true );
    // Output: <div id="first"><h1>Hello</h1></div>    

    echo innerHTML( $node, false );
    // Output: <h1>Hello</h1>
}
$html = '<div><p>ciao questa è una <b>prova</b>.</p></div>';
$dom = new DomDocument($html);
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$node = $xpath->query('.//div/*'); // with * you get inner html without surrounding div tag; without * you get inner html with surrounding div tag
$innerHtml = $dom->saveHtml($node);
var_dump($innerHtml);