Использование реализации DOM PHP для возврата первых n символов HTML - PullRequest
0 голосов
/ 20 февраля 2012

Учитывая строку HTML, я хотел бы вернуть измененную строку со следующими свойствами:

  1. Первые n символов текстового содержимого (кроме HTML-тегов) должныостаются.
  2. Элементы после n символов должны быть удалены полностью.
  3. Если n символов не находится в конце элемента,текст после этого в том же элементе не должен оставаться.
  4. Теги на элементах до и до n символов должны оставаться.

По сути, я просто хочу вернутьсокращенная версия HTML, без прерывания структуры DOM и только на основе длины текстового содержимого.

При использовании реализации DOM в PHP кажется, что это будет слишком сложно.Использование сопоставления с шаблоном не является идеальным, поскольку условия измененной строки могут со временем меняться, и для этого потребуется каждый раз переписывать.

Я упускаю более простой способ сделать это?Заранее спасибо.

1 Ответ

1 голос
/ 20 февраля 2012

"Используя реализацию PHP DOM, кажется, это будет слишком сложно."

Действительно

Вот очень простая реализация DOM, если вы хотите, чтобы первые 100 символов находились внутри тега <body> и его дочерних узлов. Вы можете дополнительно поменять это, чтобы удалить символы новой строки и лишние символы пробела / табуляции или проверить длину строки $content внутри foreach, чтобы разорвать цикл и остановить объединение, как только вы достигнете определенного количества символов.

$str = '...';
$dom = new DomDocument;
$dom->loadHTML($str);
$elements = $dom->getElementsByTagName('body');

$content = '';
foreach($elements as $node){
  foreach($node->childNodes as $child) {
    $content .= $child->nodeValue;
  }
}

echo substr($content, 0, 100);

UPDATE

Согласно вашему комментарию, вот простой способ подсчитать символы внутри узлов HTML и удалить все теги после того, как будет достигнуто указанное количество символов. Обратите внимание, что вы не можете выполнить операцию удаления внутри исходного foreach, потому что это вызывает DOM для переиндексации узлов, и вы не получите ожидаемых результатов. Вместо этого мы сохраняем узлы, которые хотим удалить, в массиве и удаляем их после начальной итерации.

$str = '...';
$dom = new DomDocument;
$dom->preserveWhitespace = FALSE;
$dom->loadHTML($str);

$elements = $dom->getElementsByTagName('body');

$remove   = FALSE;
$maxChars = 100;
$content  = '';
$delete   = array();

foreach($elements as $node){
  foreach($node->childNodes as $child) {
    if ($remove) {
      $delete[] = $child;
    } else {
      $content .= $child->nodeValue;
      if ( ! $remove && strlen($content) >= $maxChars) {
        $remove = TRUE;
      }
    }
  }
}

foreach ($delete as $child) {
  $child->parentNode->removeChild($child);
}

$dom->formatOutput = TRUE;
echo $dom->saveHTML();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...