Php 如何获取DOMNode的innerHTML?
在PHPDOM实现中,您使用什么函数获取给定DOMNode的innerHTML?有人能给出可靠的解决方案吗 当然,outerHTML也可以。此更新的变体包含: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
例如:
<?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);