2012-12-18 84 views
2

我正在嘗試使用dom對象來簡化詞彙表工具提示的實現。我需要做的是替換段落中的文本元素,而不是可能嵌入段落中的錨定標記。嘗試使用PHP 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(); 

我得到:

'...<p>Replace this element not this element</p>...' 

我想:

'...<p>Replace this element not this <a href="#">tag</a></p>...' 

如何實現這使得只有父節點文本更改和子節點(標籤)是沒有改變?

回答

2

試試這個:

$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(); 

希望這有助於。

UPDATE 要回答@保羅在下面的評論的問題,您可以創建

$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(); 
+1

非常感謝@Pushpesh。這確實很好。你能通過解釋while循環做什麼來幫助我更好地理解DOM對象。謝謝! – user1605657

+0

我一直在尋找這個問題,並且有一個擴展問題:如果我也想建立一個詞彙表,我不想只用'element'替換'tag',而是用'標籤'。因此,我會添加一個新的孩子,並且需要分割'#text'節點,對嗎?我將如何實現這一目標? – Paul

+0

@Paul看我的更新。 –