PHP:在某些HTML标记之间转义HTML实体

时间:2017-09-07 15:10:56

标签: php html escaping

让我们说我有这样的HTML:

<p>demo &</p><p>test</p><ul><li><p>Some <p><i><b>test<b/></i> text: < 15 ( less than 15 ) </p></p></li></ul><p></p>

我需要转义特殊字符(例如&#34;,&#39;,&lt;,&gt;,&amp;等),但仅限于h1,h2,p,ul,ol,li和b标签之间。所以结果应该是:

<p>demo &amp;</p><p>test</p><ul><li><p>Some <p>&lt;i&gt;<b>test</b>;&lt;\/i;&gt; text: &lt; 15 ( less than 15 ) </p></p></li></ul><p></p>

你知道怎么做吗?我尝试过使用DOMDocument,但我无法加载此HTML,因为它无效。我也尝试过更换preg,但我认为这太复杂了,无法做到这一点。

1 个答案:

答案 0 :(得分:0)

正如你所指出的那样,HTML存在各种各样的问题,我到目前为止所达到的最远的事实上是过于急切,并且倾向于重新访问已处理的文本。你也可能有一个更好的编码字符串的方法,我刚刚使用htmlspecialchars,因为它在东方尝试。

代码使用XPath查找您之后的各种节点类型,然后查看下面的文本内容,它不会解决您的所有问题,但可能会给您一个起点......

<?php 
//error_reporting(E_ALL);
//ini_set('display_errors', 1);

$html = "<p>demo &</p><p>test'\"</p><ul><li><p>Some <p><i><b>test</b></i> text: < 15 ( less than 15 ) </p></p></li></ul><p></p>";

$xml = new DOMDocument();
libxml_use_internal_errors(true);
$xml->loadHTML($html);
$xp = new DOMXPath($xml);
$tags = $xp->query("//p | //li | //i | //b | //ul | //ol | //li" );
foreach ( $tags as $tag )   {
    echo $tag->tagName.PHP_EOL;
    $content = $xp->query("descendant::text()", $tag );
    foreach ( $content as $element )    {
        if ( $element instanceof  DOMText ) {
            echo "to:".htmlspecialchars($element->wholeText).PHP_EOL;
            $newTextNode = $xml->createTextNode( htmlspecialchars($element->wholeText) );
            $element->parentNode->replaceChild( $newTextNode, $element );
        }
    }
}

echo $xml->saveXML();