Удалить пустой HTML из документа

Мне нужна помощь, удаляющая пустые теги в моем HTML. Здесь есть решение:

Удаление пустых тегов с помощью RegEx

Но я не могу использовать JS, и я никогда не должен использовать регулярные выражения для синтаксического анализа HTML .

Мне нужно очистить входы с помощью PHP, и мне также нужно получить больше, чем просто пустые теги.

Мне также нужно поймать теги следующим образом:

<p> </p> (variable whitespace with nothing in the tag) <p>&nbsp;</p> <p><br/><p> <p><br /></p> 

Что я могу сделать, чтобы поймать плохую разметку, прежде чем она попадет в базу данных (WYSIWYG)?

Solutions Collecting From Web of "Удалить пустой HTML из документа"

Разберите его с парсером модели объекта документа , проверьте текстовое содержимое узлов, удалите узлы, которые не соответствуют вашим критериям (синтаксический анализ как тег сценария, содержит пробелы, является iframe и т. Д.).

Довольно много примеров кода в разделе комментариев.

Вот куча кода, который делает что-то вроде этого (принятое из случайного вырезания + вставка на php.net)

 <?php $sampleHTML = " <p> </p> <p> &nbsp; <p> <p><br/></p> <p><br /></p> <span>Non-empty span<p id='NestedEmptyElement'></p></span> "; $doc = new DOMDocument(); $doc->loadHTML($sampleHTML); $domNodeList = $doc->getElementsByTagname('*'); $domElemsToRemove = array(); foreach ( $domNodeList as $domElement ) { $domElement->normalize(); if (trim($domElement->textContent, "\xc2\xa0 \n \t ") == "") { $domElemsToRemove[] = $domElement; } } foreach( $domElemsToRemove as $domElement ){ try { $domElement->parentNode->removeChild($domElement); } catch (Exception $e) { //node was already deleted. //There's a better way to do this, it's recursive. } } $domNodeList = $doc->getElementsByTagname('body')->item(0); $childNodes = $domNodeList->childNodes; foreach ( $childNodes as $domElement ) { echo trim($domElement->C14N()); } echo "\n\n"; 

Тогда мы бежим ..

 $ php foo.php -v <span>Non-empty span</span> 

Это соответствует вашим примерам и немного больше:

 ^<p>\s*(?:(?:&nbsp;|<br\s*/>)\s*)*</p>$ 

Но вы ищете только теги p ? Может ли быть несколько строк?

Еще одно использование normal* (special normal*)* с:

  • normal: \s ,
  • special: (&nbsp;|<br\s*/>)

(с группами, не связанными с захватом)

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

Тем не менее, у меня были огромные проблемы с DOMDocument, связанным с моими объектами html. Я бы тщательно фильтровал текст, чтобы все символы ТМ были преобразованы в объекты HTML, такие как & trade; но он преобразует их обратно в символ TM.

Я боролся с предотвращением такого поведения в течение некоторого времени. Для этого были некоторые хаки. После дня битвы я подумал: «Почему я должен так много работать, чтобы взломать его на работу? Он должен просто работать». Затем я написал эту функцию, используя simplehtmldom, как 10 минут:

 function stripEmptyTags($html){ $dom = new simple_html_dom(); $dom->load($html); foreach($dom->find("*") as $e) if( trim( str_replace( array(' ','&nbsp;'), "", $e->innertext )) == "" ) $e->outertext = ""; $dom->load($dom->save()); return $dom->save(); }