【问题标题】:php - find DOM node and replace itphp - 找到 DOM 节点并替换它
【发布时间】: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()

标签: php replace nodes domxpath


【解决方案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);
}

【讨论】:

    猜你喜欢
    • 2018-03-25
    • 1970-01-01
    • 2012-10-04
    • 2010-12-02
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 2013-07-03
    • 2011-06-04
    相关资源
    最近更新 更多