有:
$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>';
答案 0 :(得分:1)
div
和p
元素节点不是具有字符串的节点。这始终是文本节点。但是,节点可以转换为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()
会添加html
和body
元素。
对于此示例没有任何区别,但我建议对所有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();