Как я могу удалить ‹br/›, если перед ним или после него нет текста? DOMxpath или регулярное выражение?

Как я могу удалить <br/>, если перед ним или после него нет текста?

Например,

<p><br/>hello</p>
<p>hello<br/></p>

они должны быть переписаны так,

<p>hello</p>
<p>hello</p>

Должен ли я использовать DOMxpath или регулярное выражение было бы лучше?

(Примечание: у меня есть сообщение об удалении <p><br/></p> с помощью DOMxpath ранее, И тут я столкнулся с этой проблемой!)

ИЗМЕНИТЬ:

Если у меня есть это на входе,

$content = '<p><br/>hello<br/>hello<br/></p>';

тогда это должно быть

<p>hello<br/>hello</p>'

person laukok    schedule 27.07.2011    source источник
comment
Что делать, если у вас есть что-то вроде <p>hello<br><i>world</i></p>? В таком случае вы хотите удалить <br/>?   -  person netcoder    schedule 27.07.2011
comment
@netcoder, спасибо, что указали на это - в таком случае сохраните :-)   -  person laukok    schedule 27.07.2011
comment
Позвольте мне понять, чего вы хотите достичь, и я опубликую свои 2 цента.   -  person Ken D    schedule 27.07.2011
comment
Надеюсь, у вас не будет такой ситуации, как <br/><br/>.   -  person Emiliano Poggi    schedule 27.07.2011
comment
да у меня ситуация как <br/><br/>... и я использую pre_replace для решения этой ситуации - $content = preg_replace('/(<br\s*\/?>\s*)+/', '<br/>', $content);   -  person laukok    schedule 27.07.2011


Ответы (2)


Для выбора упомянутого br вы можете использовать:

 "//p[node()[1][self::br]]/br[1] | //p[node()[last()][self::br]]/br[last()]"

или (может быть) быстрее:

 "//p[br]/node()[self::br and (position()=1 or position()=last())]"

Просто получить br, когда первый (или последний) узел p равен br.

Это выберет br, например:

<p><br/>hello</p>
<p>hello<br/></p>

и первый и последний br, как в:

<p><br/>hello<br/>hello<br/></p>

не средний бр, как в:

<p>hello<br/>hello</p>

PS: чтобы получить в итоге первый бр в паре вот так <br/><br/>:

"//br[following::node()[1][self::br]]"
person Emiliano Poggi    schedule 27.07.2011
comment
Спасибо эмпо! У меня проблема с '<p><br/>hello<br/>hello<br/></p>'. Пожалуйста, посмотрите мое редактирование выше. Спасибо! - person laukok; 27.07.2011
comment
обновлен хорошей альтернативой и бонусом за br пар. Ваше здоровье - person Emiliano Poggi; 27.07.2011

В случае некоторого кода я мог бы заставить его работать так (Демо). Он имеет небольшую модификацию xpath @empo (очень немного) и показывает удаление совпадений, а также еще несколько тестовых случаев:

$html = <<<EOD
<p><br/>hello</p>
<p>hello<br/></p>
<p>hello<br/>Chello</p>
<p>hello <i>molly</i><br/></p>
<p>okidoki</p>
EOD;

$doc = new DomDocument;
$doc->loadHTML($html);
$xpath = new DomXPath($doc);
$nodes = $xpath->query('//p[node()[1][self::br] or node()[last()][self::br]]/br');
foreach($nodes as $node) {
    $node->parentNode->removeChild($node);
}
var_dump($doc->saveHTML());
person hakre    schedule 27.07.2011