How can I remove <br/> if no text comes before or after it? DOMxpath or regex?

人盡茶涼 提交于 2019-12-10 13:45:15

问题


How can I remove <br/> if no text comes before or after it?

For instance,

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

they should be rewritten like this,

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

Should I use DOMxpath or regex would be better?

(Note: I have a post about removing <p><br/></p> with DOMxpath earlier, and then I came across this issue!)

EDIT:

If I have this in the input,

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

then it should be

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

回答1:


To select the mentioned br you can use:

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

or, (maybe) faster:

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

Just getting the br when the first (or last) node of p is br.

This will select br such as:

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

and first and last br like in:

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

not middle br like in:

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

PS: to get eventually the first br in a pair like this <br/><br/>:

"//br[following::node()[1][self::br]]"



回答2:


In case for some code, I could get it to working like this (Demo). It has a slight modification from @empo's xpath (very slightly) and shows the removal of the matches as well as some more test-cases:

$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());


来源:https://stackoverflow.com/questions/6844646/how-can-i-remove-br-if-no-text-comes-before-or-after-it-domxpath-or-regex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!