如何使用XPath和DOM替换PHP中的节点/元素? [英] How can I use XPath and DOM to replace a node/element in php?
问题描述
$ 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);
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屋!