0

我有一个 HTML 字符串,我想从中删除所有类为“toremove”的 DIV。

这在客户端使用 jQuery 等很简单,但我想在服务器端使用 PHP。

一个简单的 aegular 表达式是行不通的,因为 div 可能是嵌套的……

4

4 回答 4

2

您可以使用 DOM 对象和 xPath 来删除 DIV。

/** UNTESTED **/
$doc = new DOMDocument();
$doc->loadHTMLFile($file);

$xpath = new DOMXpath($doc);
$elements = $xpath->query("*/div[@class='yourClasshere']");

foreach($elements as $e){
    $doc->removeChild($e);
}
$doc->saveHTMLFile($file);

如果您愿意,可以用 load from 和 save to string 替换从文件加载和保存到文件。

于 2012-10-12T12:57:42.977 回答
1

这是我用来从页面中删除内容的代码片段:

/**
 * A method to remove unwanted parts of an HTML-page. Can remove elements by 
 * id, tag name and/or class names. 
 *
 * @param string $html The HTML to manipulate
 * @param array $partsToRemove An array of arrays, with the keys specifying 
 * what type of values the array holds. The following keys are used:
 * 'elements' - An array of element ids to remove from the html 
 * 'tags' - An array of tag names to remove from the html
 * 'classNames' - An array of class names. Each tag that contains one of the 
 * class names will be removed from the html.
 *
 * Also, note that descendants of the removed document will also be removed.
 * 
 * @return string The manipulated HTML content
 *
 * @example removeHtmlParts($html, array (
 *  'elements' => array ('headerSection', 'nav', 'footerSection'),
 *  'tags' => array ('form'),
 *  'classNames' => array ('promotion')
 *  ));
 */

--

public function removeHtmlParts ($html, array $toRemove = array())
{
$document = new \DOMDocument('1.0', 'UTF-8');
$document->encoding = 'UTF-8';
// Hack to force DOMDocument to load the HTML using UTF-8.
@$document->loadHTML('<?xml encoding="UTF-8">' . $response->getBody());
$partsToRemove = array ();
if(isset($toRemove['elements']))
{
  $partsToRemove['elements'] = $toRemove['element'];
}
if(isset($toRemove['tags']))
{
  $partsToRemove['tags'] = $toRemove['tags'];
}
if(isset($toRemove['classNames']))
{
  $partsToRemove['classNames'] = $toRemove['classNames'];
}

foreach ($partsToRemove as $type => $content)
{
    if($type == 'elements')
    {
        foreach ($content as $elementId)
        {
            $element = $document->getElementById($elementId);
            if($element)
            {
                $element->parentNode->removeChild($element);
            }
        }
    }
    elseif($type == 'tags')
    {
        foreach($content as $tagName)
        {
            $tags = $document->getElementsByTagName($tagName);
            while($tags->length)
            {
                $tag = $tags->item(0);
                if($tag)
                {
                    $tag->parentNode->removeChild($tag);
                }
            }
        }
    }
    elseif($type == 'classNames')
    {
        foreach ($content as $className)
        {
            $xpath = new \DOMXPath($document);
                    $xpathExpression = sprintf(
                       '//*[contains(@class,"%1")]', 
                       $className
                    ); 
            $domNodeList = $xpath->evaluate($xpathExpression);
            for($i = 0; $i < $domNodeList->length; $i++)
            {
                $node = $domNodeList->item($i);
                if($node && $node->parentNode)
                {
                    $node->parentNode->removeChild($node);
                }
            }
        }
    }
}
return $document->saveHTML();
}

笔记:

  • 此代码未经过适当的单元测试,可能在边缘情况下包含错误
  • 应该将此方法重构为一个类,并将方法的内容拆分为单独的方法以方便测试。
于 2012-10-12T13:18:46.053 回答
1

基于 jebbench 的简短回答和 PatrikAkerstrand 的长回答,我创建了一个可以完全解决我的问题的中型函数:

/**
 * remove, from the given xhtml string, all divs with the given class.
 */
function remove_divs_with_class($xhtml, $class) {
    $doc = new DOMDocument();

    // Hack to force DOMDocument to load the HTML using UTF-8:
$doc->loadHTML('<?xml encoding="UTF-8">'.$xhtml); 

    $xpath = new DOMXpath($doc);
    $elements = $xpath->query("//*[contains(@class,'$class')]");

    foreach  ($elements as $element)
        $element->parentNode->removeChild($element);

    return $doc->saveHTML();
}

/* UNIT TEST */
if (basename(__FILE__)==basename($_SERVER['PHP_SELF'])) {
    $xhtml = "<div class='near future'>near future</div><div>start</div><div class='future'>future research</div><div class='summary'>summary</div><div class='a future b'>far future</div>";
    $xhtml2 = remove_divs_with_class($xhtml, "future");
    print "<h2>before</h2>$xhtml<h2>after</h2>$xhtml2";
}

/* OUTPUT:

before

near future
start
future research
summary
far future

after

start
summary

*/
于 2012-10-12T13:32:12.567 回答
-1

永远不要尝试使用正则表达式来解析 XML/HTML。而是使用解析库。显然,PHP 的一个是http://sourceforge.net/projects/simplehtmldom/files/

于 2012-10-12T12:46:44.187 回答