尝试使用PHP DOM替换节点文本而不更改子节点

尝试使用PHP DOM替换节点文本而不更改子节点,php,dom,domdocument,Php,Dom,Domdocument,我试图使用dom对象简化术语表工具提示的实现。我需要做的是替换段落中的文本元素,而不是替换可能嵌入到段落中的锚定标记中的文本元素 $html = '<p>Replace this tag not this <a href="#">tag</a></p>'; $document = new DOMDocument(); $document->loadHTML($html); $document->preserveWhiteSpace =

我试图使用dom对象简化术语表工具提示的实现。我需要做的是替换段落中的文本元素,而不是替换可能嵌入到段落中的锚定标记中的文本元素

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementByTagName("p");
foreach ($nodes as $node) {
  $node->nodeValue = str_replace("tag","element",$node->nodeValue);
}
echo $document->saveHTML();
$html='替换此标签而不是此标签;
$document=新的DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace=false;
$document->validateOnParse=true;
$nodes=$document->getElementByTagName(“p”);
foreach($node作为$node){
$node->nodeValue=str_replace(“标记”,“元素”,“$node->nodeValue”);
}
echo$document->saveHTML();
我得到:

'...<p>Replace this element not this element</p>...'
“…替换此元素而不是此元素”
我想:

'...<p>Replace this element not this <a href="#">tag</a></p>...'
“…替换此元素而不是此”
如何实现这一点,以便只更改父节点文本,而不更改子节点(标记)?

尝试以下操作:

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementsByTagName("p");

foreach ($nodes as $node) {
    while( $node->hasChildNodes() ) {
        $node = $node->childNodes->item(0);
    }
    $node->nodeValue = str_replace("tag","element",$node->nodeValue);
}
echo $document->saveHTML();
$html='替换此标签而不是此标签;
$document=新的DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace=false;
$document->validateOnParse=true;
$nodes=$document->getElementsByTagName(“p”);
foreach($node作为$node){
而($node->hasChildNodes()){
$node=$node->childNodes->item(0);
}
$node->nodeValue=str_replace(“标记”,“元素”,“$node->nodeValue”);
}
echo$document->saveHTML();
希望这有帮助

更新 要在下面的评论中回答@paul的问题,您可以创建

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementsByTagName("p");

//create the element which should replace the text in the original string
$elem = $document->createElement( 'dfn', 'tag' );
$attr = $document->createAttribute('title');
$attr->value = 'element';
$elem->appendChild( $attr );

foreach ($nodes as $node) {
    while( $node->hasChildNodes() ) {
        $node = $node->childNodes->item(0);
    }
    //dump the new string here, which replaces the source string
    $node->nodeValue = str_replace("tag",$document->saveHTML($elem),$node->nodeValue);
}
echo $document->saveHTML();
$html='替换此标签而不是此标签;
$document=新的DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace=false;
$document->validateOnParse=true;
$nodes=$document->getElementsByTagName(“p”);
//创建应替换原始字符串中文本的元素
$elem=$document->createElement('dfn','tag');
$attr=$document->createAttribute('title');
$attr->value='element';
$elem->appendChild($attr);
foreach($node作为$node){
而($node->hasChildNodes()){
$node=$node->childNodes->item(0);
}
//在此处转储新字符串,以替换源字符串
$node->nodeValue=str_replace(“tag”、$document->saveHTML($elem)、$node->nodeValue);
}
echo$document->saveHTML();

非常感谢@Pushpesh。这确实很有效。你能通过解释while循环的作用来帮助我更好地理解DOM对象吗。谢谢我也在寻找它,并且有一个扩展问题:如果我还想构建一个术语表,我不想仅仅用
元素
替换
标记
,而是用
标记
。因此,我将添加一个新的子节点,需要拆分
#text
节点,对吗?我将如何实现这一点?谢谢分享。我尝试了同样的方法,但将HTML放入文本节点是行不通的。最后我使用了DOMDocumentFragment并用该片段替换了#text节点。由于while循环,不适用于替换此标记,而不是此标记和此标记。