Заменить часть строки в зависимости от содержимого строки - PullRequest
3 голосов
/ 02 апреля 2011

Пример разметки:

<code><p> a paragraph </p>
<pre lang="html">
  &lt;p&gt; a paragraph &lt;/p&gt;

абзац

Как выбрать все вещи между <pre>, </pre>,<code>, и запустить на нем функцию?Через эту функцию мне нужно передать 3 аргумента: часть выбранной строки (&lt;p&gt; a paragraph &lt;/p&gt;), тип контейнера (pre или code) и параметры контейнера (например, lang="html").

Функция должна изменить выбранную часть строки на основе двух других параметров (если это уместно, я хочу запустить на ней подсветку GeShi ), а затем заменить содержимое исходной строки наэто, включая контейнер.Что-то вроде:

<p> a paragraph </p>
<div class="html pre">
  &lt;p&gt; a paragraph &lt;/p&gt;
</div>
<div class="html code">
  &lt;p&gt; a paragraph &lt;/p&gt;
</div>

1 Ответ

3 голосов
/ 02 апреля 2011

Я думаю, что так должно быть:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);

$elements = $xpath->query('//pre | //code');

В некоторых случаях (например, если вы используете getElementsByTagName вместо XPath), вам нужно работать с массивом, чтобы получить правильное поведение (см. этот вопрос ), поэтому вам необходимо скопировать узлы в массив. Я сделаю это для этого примера:

$array = array();
foreach ($elements as $element) {
    $array[] = $element;
}

foreach ($array as $element) {
    $tag = $element->tagName;
    $content = $element->textContent;
    $lang = $element->getAttribute('lang');
    $new_content = my_function($tag, $content, $lang);

    $new_element = $dom->createElement('div');
    $new_element->setAttribute('class', "$tag $lang");
    $new_element->nodeValue = $new_content;
    $element->parentNode->replaceChild($new_element, $element);
}

Конечно, в приведенном выше примере my_function не определено. Но это должно дать вам хорошее представление о том, как это сделать.

Обратите внимание, что это не будет работать на вложенных элементах, например:

<code><pre lang="html">
  <p>some nested element</p>
  &lt;p&gt; a paragraph &lt;/p&gt;

Если вы хотите работать с вложенными элементами, используйте функцию для получения innerHTML вместо использования $element->textContent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...