php - 找到 DOM 节点并替换它
Posted
技术标签:
【中文标题】php - 找到 DOM 节点并替换它【英文标题】:php - find DOM node and replace it 【发布时间】:2015-11-11 14:59:42 【问题描述】:我想解析一个 DOM 并从数据属性名称中找到一个特定的节点。 然后我想用另一个 dom 替换它。
我成功找到了 DOM 节点,但替换它有些困难。 这是我的代码:
$content = '<article class="post-35">
<div class="inner">
<div class="holder dark">
<div class="media"></div>
<i class="icon-play"></i>
<i class="icon-link"></i>
</div>
<span class="item-date">July 3, 2015</span>
<h2 class="item-title"><a href="">A title</a></h2>
<span class="post-like" data-post-id="35" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 64 64"><g><path></path></g></svg>
<span class="like-count">2</span>
</span>
</div>
</article>
<article class="post-36">
<div class="inner">
<div class="holder dark">
<div class="media"></div>
<i class="icon-play"></i>
<i class="icon-link"></i>
</div>
<span class="item-date">July 3, 2015</span>
<h2 class="item-title"><a href="">A title</a></h2>
<span class="post-like" data-post-id="36" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 64 64"><g><path></path></g></svg>
<span class="like-count">5</span>
</span>
</div>
</article>';
$dom = new DOMDocument();
@$dom->loadhtml($content);
$finder = new DOMXPath($dom);
$nodes = $finder->query('//span[@data-post-id]/@data-post-id');
foreach ($nodes as $node)
$like = post_like($node->value); // '<span class="my-class"><svg></svg><span>xx</span>'
$like = $dom->createElement('span',$like);
//$node->parentNode->parentNode->appendChild($like); // this works but append plain text not html...
$node->parentNode->replaceChild($like, $node); // fatal error Uncaught exception 'DOMException' with message 'Not Found Error'
怎么了?
编辑:
当我 print_r 节点时,我得到了这个:
DOMAttr Object
(
[name] => post-id
[specified] => 1
[value] => 35
[ownerElement] => (object value omitted)
[schemaTypeInfo] =>
[nodeName] => post-id
[nodeValue] => 35
[nodeType] => 2
[parentNode] => (object value omitted)
[childNodes] => (object value omitted)
[firstChild] => (object value omitted)
[lastChild] => (object value omitted)
[previousSibling] => (object value omitted)
[nextSibling] => (object value omitted)
[attributes] =>
[ownerDocument] => (object value omitted)
[namespaceURI] =>
[prefix] =>
[localName] => post-id
[baseURI] =>
[textContent] => 35
)
【问题讨论】:
你提到的困难是什么?你有任何错误信息吗?问题的任何其他视觉表现? 我在 replacechild 行出现错误。我已在评论中添加错误。 好吧,阅读错误消息是值得的:Wrong Document Error
。您在不同的DOMDocument
中创建了一个新节点,因此您无法将其插入到之前的节点中。
使用相同的 dom 我遇到了这个错误:未捕获的异常 'DOMException' 带有消息 'Not Found Error'
你能多发一点 HTML 部分吗?也许post_like()
?
【参考方案1】:
我认为您应该使用相同的文档来创建您的元素:
$content = '<div>.....</div>';
$dom = new DOMDocument();
@$dom->loadHTML($content);
$finder = new DOMXPath($dom);
$nodes = $finder->query('//span[@data-post-id]/@data-post-id');
foreach ($nodes as $node)
$like = post_like($node->value); // return html string (<span>...</span>)
$like = $dom->createElement('span',$like);
$node->parentNode->replaceChild($like, $node);
【讨论】:
感谢您的回答。这是我的第一次尝试,但我的代码有一个错误:未捕获的异常 'DOMException' 和消息 'Not Found Error'... 我编辑了我的问题并在 foreach 循环中添加了节点的打印。似乎缺少 parentNode 但我不知道为什么...【参考方案2】:您可以使用 DOMDocumentFragment appendXML 方法将节点的“字符串”正确添加到现有 DOM。
foreach ($nodes as $node)
$like = post_like($node->value);
$frag = $dom->createDocumentFragment();
$frag->appendXML("<span>" . $like . "</span>");
$node->parentNode->parentNode->appendChild($frag);
【讨论】:
以上是关于php - 找到 DOM 节点并替换它的主要内容,如果未能解决你的问题,请参考以下文章
Javascript进阶篇——(DOM—节点---插入删除和替换元素创建元素创建文本节点)—笔记整理
JavaScript之DOM-5 增加删除和替换节点(创建节点插入节点删除和替换节点)