問題描述
我正在嘗試使用 simple_html_dom php 類來創建查找和替換關鍵字的查找和替換函數并將它們替換為關鍵字定義的鏈接,并將關鍵字作為鏈接文本.
我如何使用此類在字符串中找到并用 Dexia</a>
替換Dexia",例如<div><p>德克夏銀行的CEO剛剛決定退休.</p></div>
?
這有點棘手,但你可以這樣做:
$html = <<<HTML<div><p>德克夏銀行的首席執行官<em>已經</em>剛剛決定退休.</p></div>HTML;
我添加了一個強調元素只是為了說明它也適用于內聯元素.
設置
$dom = 新的 DOMDocument;$dom->formatOutput = TRUE;$dom->loadXML($html);$xpath = new DOMXPath($dom);$nodes = $xpath->query('//text()[contains(., "Dexia")]');
上面有趣的當然是XPath.它為所有包含針Dexia"的 DOMText
節點查詢加載的 DOM.結果是 DOMNodeList
(像往常一樣).
替換
foreach($nodes as $node) {$link = '<a href="info.php?tag=dexia">Dexia</a>';$replaced = str_replace('Dexia', $link, $node->wholeText);$newNode = $dom->createDocumentFragment();$newNode->appendXML($replaced);$node->parentNode->replaceChild($newNode, $node);}echo $dom->saveXML($dom->documentElement);
找到的 $node
將包含 wholeText
的字符串 The CEO of the Dexia bank ,盡管它在 P 中
元素.那是因為 $node
有一個兄弟 DOMElement
,重點放在 bank 之后.我將鏈接創建為字符串而不是節點,并用它替換 wholeText
中所有出現的Dexia"(不管詞邊界如何 - 這將是對 Regex 的一個很好的調用).然后我從結果字符串創建一個 DocumentFragment
并用它替換 DOMText
節點.
W3C 與 PHP
使用DocumentFragement::applyXML()
是一種非標準方法,因為該方法不是 W3C DOM 規范的一部分.
如果您想用標準 API 進行替換,您首先必須將 A
元素創建為新的 DOMElement
.然后你必須在 DOMText
的 nodeValue
中找到Dexia"的偏移量,然后將 DOMText
節點拆分為兩個節點位置.從返回的兄弟中移除 Dexia 并在第二個之前插入 Link 元素.對同級節點重復此過程,直到在節點中找不到更多的 Dexia 字符串.以下是針對一次德克夏的處理方法:
foreach($nodes as $node) {$link = $dom->createElement('a', 'Dexia');$link->setAttribute('href', 'info.php?tag=dexia');$offset = strpos($node->nodeValue, '德克夏');$newNode = $node->splitText($offset);$newNode->deleteData(0, strlen('Dexia'));$node->parentNode->insertBefore($link, $newNode);}
最后是輸出
<p><a href="info.php?tag=dexia">Dexia</a>的CEO銀行<em>有</em>剛剛決定退休.</p>
I'm trying to use the simple_html_dom php class to create a find and replace function that looks for keywords and replace them by a link to a definition of the keyword, with the keyword as link text.
How can i find and replace "Dexia" with <a href="info.php?tag=dexia">Dexia</a>
using this class, inside a string such as <div><p>The CEO of the Dexia bank has just decided to retire.</p></div>
?
That's somewhat tricky, but you could do it this way:
$html = <<< HTML
<div><p>The CEO of the Dexia bank <em>has</em> just decided to retire.</p></div>
HTML;
I've added an emphasis element just to illustrate that it works with inline elements too.
Setup
$dom = new DOMDocument;
$dom->formatOutput = TRUE;
$dom->loadXML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//text()[contains(., "Dexia")]');
The interesting thing above is the XPath of course. It queries the loaded DOM for all DOMText
nodes containing the needle "Dexia". The result is DOMNodeList
(as usual).
The replacement
foreach($nodes as $node) {
$link = '<a href="info.php?tag=dexia">Dexia</a>';
$replaced = str_replace('Dexia', $link, $node->wholeText);
$newNode = $dom->createDocumentFragment();
$newNode->appendXML($replaced);
$node->parentNode->replaceChild($newNode, $node);
}
echo $dom->saveXML($dom->documentElement);
The found $node
will contain the string The CEO of the Dexia bank for wholeText
, despite it being inside the P
element. That is because the $node
has a sibling DOMElement
with the emphasis after bank. I am creating the link as a string instead of a node and replace all occurences of "Dexia" (regardless of word boundary - that would be a good call for Regex) in the wholeText
with it. Then I create a DocumentFragment
from the resulting string and replace the DOMText
node with it.
W3C vs PHP
Using DocumentFragement::applyXML()
is a non-standard approach, because the method is not part of the W3C DOM Specs.
If you would want to do the replacement with the standard API, you'd first have to create the A
Element as a new DOMElement
. Then you'd have to find the offset of "Dexia" in the nodeValue
of the DOMText
and split the DOMText
Node into two nodes at that position. Remove Dexia from the returned sibling and insert the Link Element, before the second one. Repeat this procedure with the sibling node until no more Dexia strings are found in the node. Here is how to do it for one occurence of Dexia:
foreach($nodes as $node) {
$link = $dom->createElement('a', 'Dexia');
$link->setAttribute('href', 'info.php?tag=dexia');
$offset = strpos($node->nodeValue, 'Dexia');
$newNode = $node->splitText($offset);
$newNode->deleteData(0, strlen('Dexia'));
$node->parentNode->insertBefore($link, $newNode);
}
And finally the output
<div>
<p>The CEO of the <a href="info.php?tag=dexia">Dexia</a> bank <em>has</em> just decided to retire.</p>
</div>
這篇關于通過 php dom 在 html 片段中通過超鏈接查找和替換關鍵字的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!