Как я могу удалить <br/>, если до или после него нет текста? DOMxpath или регулярное выражение? - PullRequest
5 голосов
/ 27 июля 2011

Как я могу удалить <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>'

Ответы [ 2 ]

4 голосов
/ 27 июля 2011

Чтобы выбрать упомянутый 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, когда первый (или последний) узелр бр.

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

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

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

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

не средний br как в:

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

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

"//br[following::node()[1][self::br]]"
0 голосов
/ 27 июля 2011

В случае некоторого кода, я мог бы заставить его работать так ( Demo ). Он имеет небольшую модификацию из 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());
...