найдите и замените ключевые слова гиперссылками во фрагменте HTML через php dom

Я пытаюсь использовать simple_html_dom php класс для создания находки и функции замены, которая ищет ключевые слова, и замените их ссылкой на определение ключевого слова с ключевым словом как текст ссылки.

Как я могу найти и заменить "Dexia" с Dexia использование этого класса, в строке такой как

The CEO of the Dexia bank has just decided to retire.

?

6
задан pixeline 30 June 2010 в 15:57
поделиться

1 ответ

Это несколько сложно, но вы можете сделать это следующим образом:

$html = <<< HTML
<div><p>The CEO of the Dexia bank <em>has</em> just decided to retire.</p></div>
HTML;

Я добавил элемент выделения, чтобы показать, что он работает с встроенные элементы тоже.

Настройка

$dom = new DOMDocument;
$dom->formatOutput = TRUE;
$dom->loadXML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//text()[contains(., "Dexia")]');

Интересное, что вы видите выше, это, конечно же, XPath. Он запрашивает загруженную модель DOM для всех узлов DOMText , содержащих иглу «Dexia». Результатом будет 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);

Найденный узел $ будет содержать строку CEO банка Dexia для wholeText , несмотря на то, что он находится внутри ] P элемент. Это связано с тем, что узел $ имеет родственника DOMElement с выделением после банка . Я создаю ссылку в виде строки вместо узла и заменяю им все вхождения «Dexia» (независимо от границы слова - это было бы хорошим призывом для Regex) в wholeText .Затем я создаю DocumentFragment из полученной строки и заменяю им узел DOMText .

W3C vs PHP

Использование DocumentFragement :: applyXML () - нестандартный подход, поскольку этот метод не является частью спецификаций W3C DOM.

Если вы хотите произвести замену с помощью стандартного API, вам сначала нужно создать элемент A как новый DOMElement . Затем вам нужно будет найти смещение «Dexia» в nodeValue DOMText и разделить узел DOMText на два узла в этой позиции. Удалите Dexia из возвращенного брата и вставьте элемент связи перед вторым. Повторите эту процедуру с соседним узлом, пока в узле не перестанут быть строки Dexia. Вот как это сделать для одного случая использования 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);
}

И, наконец, результат

<div>
  <p>The CEO of the <a href="info.php?tag=dexia">Dexia</a> bank <em>has</em> just decided to retire.</p>
</div>
5
ответ дан 17 December 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: