使用DOMDocument删除内容长度较短的节点

时间:2014-06-02 16:54:19

标签: php html-parsing domdocument removechild

有:

$content= 
'<div id="parent">
    <div class="children">
        This is short content
    </div>
    <div class="children">
        This is a very long content even longer than the Short content
    </div>
    <p>
        This is a Short content in a paragraph
    </p>
        This is a Short content without a html elemnt
</div>';

我可以使用class(或id)使用DOMDocument删除节点,如下所示:

$dom->loadHTML($content);
$xpath = new DOMXpath($dom);
if($divToRemove = $xpath->query('.//div[@class="children"]')->item(0))
    $divToRemove->parentNode->removeChild($divToRemove);
$content = $dom->saveHTML();

使用上面的代码,我可以从div删除第一个$content。但是如何删除内部文本较短的子项,例如短于20个字符?

修改
我不知道子元素。它可以是<div><p>或其他内容 我想删除父母<div>的每个短长子 是否有任何Xpath查询来选择节点的长度?

这就是我想要输出的内容:

$content= 
'<div id="parent">
    <div class="children">
        This is a very long content even longer than the Short content
    </div>
</div>';

2 个答案:

答案 0 :(得分:1)

divp元素节点不是具有字符串的节点。这始终是文本节点。但是,节点可以转换为Xpath中的字符串。这是需要的两个字符串函数。

string-length()

返回字符串的字符长度。如果提供了节点列表,则列表的第一个节点将转换为字符串。

normalize-space()

将字符串中的所有空格组转换为单个空格,并从开始和结束中删除它们。

但首先得到一些背景信息:

$context = $xpath->evaluate('//div[@id = "parent"]')->item(0);

现在为具有排序内容的节点构建表达式:

所有类型的节点,元素,文本节点,评论......

node()

...在规范化空格后,字符串长度小于或等于50:

node()[string-length(normalize-space(.)) <= 50]

放在一起:

$dom = new DOMDocument();
$dom->loadHtml($content);
$xpath = new DOMXPath($dom);

$context = $xpath->evaluate('//div[@id = "parent"]')->item(0);

$maxLength = 50;
$expression = 'node()[string-length(normalize-space(.)) <= '.$maxLength.']';
foreach ($xpath->evaluate($expression, $context) as $node) {
  $node->parentNode->removeChild($node);
}

echo $dom->saveHtml($context);

输出:

<div id="parent"><div class="children">
        This is a very long content even longer than the Short content
    </div></div>

上下文用于仅将原始div保存为HTML。 DOMDocument::loadHtml()会添加htmlbody元素。

对于此示例没有任何区别,但我建议对所有Xpath表达式使用DOMXpath::evaluate()DOMXpath::query()不支持返回标量值的Xpath表达式。请参阅:https://stackoverflow.com/a/23796070/2265374

答案 1 :(得分:0)

$dom->loadHTML($content);
$xpath = new DOMXpath($dom);

if($divToRemove = $xpath->query('.//div[@class="children"]')->item(0)) {
    if(20 > strlen($xpath->query('.//div[@class="children"]')->item(0))) {
        $divToRemove->parentNode->removeChild($divToRemove);
    }
}

$content = $dom->saveHTML();