如何使用XPath和DOM替换PHP中的节点/元素? [英] How can I use XPath and DOM to replace a node/element in php?

查看:103
本文介绍了如何使用XPath和DOM替换PHP中的节点/元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下html

  $ html ='
< div class =website> ;
< div>
< div id =old_div>
< p>某些文字< / p>
< p>某些文字< / p>
< p>某些文字< / p>
< p>某些文字< / p>
< div class =a class>
< p>某些文字< / p>
< p>某些文字< / p>
< / div>
< / div>
< div id =another_div>< / div>
< / div>
< / div>
';

而我想将 #old_div 替换为以下:

  $ replacement ='< div id =new_div>这是新的< / div>'; 

给出最终结果:

  $ html ='
< div class =website>
< div>
< div id =new_div>这是新的< / div>
< div id =another_div>< / div>
< / div>
< / div>
';

有没有一个简单的剪切和粘贴功能来做这个PHP?






由于所有Gordon的帮助,最终的工作代码:

 <?php 

$ html =<<< HTML
< div class =website>
< div>
< div id =old_div>
< p>某些文字< / p>
< p>某些文字< / p>
< p>某些文字< / p>
< p>某些文字< / p>
< div class =a class>
< p>某些文字< / p>
< p>某些文字< / p>
< / div>
< / div>
< div id =another_div>< / div>
< / div>
< / div>
HTML;

$ dom = new DOMDocument;
$ dom-> loadXml($ html); //使用loadHTML,如果它是无效的XHTML

//创建替换
$ replacement = $ dom-> createDocumentFragment();
$ replacement - > appendXML('< div id =new_div>这是新的< / div>');

// make replacement
$ xp = new DOMXPath($ dom);
$ oldNode = $ xp-> query('// div [@ id =old_div]') - > item(0);
$ oldNode-> parentNode-> replaceChild($ replacement,$ oldNode);
//保存html输出
$ new_html = $ dom-> saveXml($ dom-> documentElement);

echo $ new_html;

?>


解决方案

由于链接的副本中的答案不是全面的我举一个例子:

  $ dom = new DOMDocument; 
$ dom-> loadXml($ html); //使用loadHTML如果它的无效(X)HTML

//创建新元素
$ newNode = $ dom-> createElement('div','this is new');
$ newNode-> setAttribute('id','new_div');

//获取并替换旧元素
$ oldNode = $ dom-> getElementById('old_div');
$ oldNode-> parentNode-> replaceChild($ newNode,$ oldNode);

// print xml
echo $ dom-> saveXml($ dom-> documentElement);






从技术上讲,您不需要XPath 。但是,您的libxml版本不能对未经验证的文档执行 getElementById id属性在XML中是特殊的)。在这种情况下,将呼叫替换为 getElementById

  $ xp =新的DOMXPath($ dom); 
$ oldNode = $ xp-> query('// div [@ id =old_div]') - > item(0);

在键盘上演示






创建一个 $ newNode 与子节点,而不必逐个创建和追加元素,您可以执行

  $ newNode = $ dom-> ; createDocumentFragment(); 
$ newNode-> appendXML('
< div id =new_div>
< p>其他一些文本< / p>
< p>其他文字< / p>
< p>某些其他文字< / p>
< p>其他文字< / p>
< / div>
' );


Say I have the following html

$html = '
<div class="website">
    <div>
        <div id="old_div">
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <div class="a class">
                <p>some text</p>
                <p>some text</p>
            </div>
        </div>
        <div id="another_div"></div>
    </div>
</div>
';

And I want to replace #old_div with the following:

$replacement = '<div id="new_div">this is new</div>';

To give an end result of:

$html = '
<div class="website">
        <div>
            <div id="new_div">this is new</div>
            <div id="another_div"></div>
        </div>
    </div>
';

Is there an easy cut-and-paste function for doing this with PHP?


Final working code thanks to all Gordon's help:

<?php

$html = <<< HTML
<div class="website">
    <div>
        <div id="old_div">
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <div class="a class">
                <p>some text</p>
                <p>some text</p>
            </div>
        </div>
        <div id="another_div"></div>
    </div>
</div>
HTML;

$dom = new DOMDocument;
$dom->loadXml($html); // use loadHTML if it's invalid XHTML

//create replacement
$replacement  = $dom->createDocumentFragment();
$replacement  ->appendXML('<div id="new_div">this is new</div>');

//make replacement
$xp = new DOMXPath($dom);
$oldNode = $xp->query('//div[@id="old_div"]')->item(0);
$oldNode->parentNode->replaceChild($replacement  , $oldNode);
//save html output
$new_html = $dom->saveXml($dom->documentElement);

echo $new_html;

?>

解决方案

Since the answer in the linked duplicate is not that comprehensive, I'll give an example:

$dom = new DOMDocument;
$dom->loadXml($html); // use loadHTML if its invalid (X)HTML

// create the new element
$newNode = $dom->createElement('div', 'this is new');
$newNode->setAttribute('id', 'new_div');

// fetch and replace the old element
$oldNode = $dom->getElementById('old_div');
$oldNode->parentNode->replaceChild($newNode, $oldNode);

// print xml
echo $dom->saveXml($dom->documentElement);


Technically, you don't need XPath for this. However, it can happen that your version of libxml cannot do getElementById for non-validated documents (id attributes are special in XML). In that case, replace the call to getElementById with

$xp = new DOMXPath($dom);
$oldNode = $xp->query('//div[@id="old_div"]')->item(0);

Demo on codepad


To create a $newNode with child nodes without having to to create and append elements one by one, you can do

$newNode = $dom->createDocumentFragment();
$newNode->appendXML('
<div id="new_div">
    <p>some other text</p>
    <p>some other text</p>
    <p>some other text</p>
    <p>some other text</p>
</div>
');

这篇关于如何使用XPath和DOM替换PHP中的节点/元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆