Эта функция должна делать то, что вы хотите.Учитывая DOMDocument
($doc
) и узел ($node
) для поиска, он рекурсивно перебирает дочерние элементы этого узла, удаляя любые теги, которые не находятся в массиве $allowed_tags
и для тех тегов, которые хранятся, удаляются любые атрибуты, отсутствующие в массиве $allowed_attributes
:
function remove_nodes_and_attributes($doc, $node, $allowed_tags, $allowed_attributes) {
$xpath = new DOMXPath($doc);
foreach ($xpath->query('./*', $node) as $child) {
if (!in_array($child->nodeName, $allowed_tags)) {
$node->removeChild($child);
continue;
}
$a = 0;
while ($a < $child->attributes->length) {
$attribute = $child->attributes->item($a)->name;
if (!in_array($attribute, $allowed_attributes)) {
$child->removeAttribute($attribute);
// don't increment the pointer as the list will shift with the removal of the attribute
}
else {
// allowed attribute, skip it
$a++;
}
}
// remove any children as necessary
remove_nodes_and_attributes($doc, $child, $allowed_tags, $allowed_attributes);
}
}
. Вы бы использовали эту функцию следующим образом.Обратите внимание, что необходимо обернуть HTML в элемент верхнего уровня, который затем снова удаляется в конце, используя substr
.
$doc = new DOMDocument();
$doc->loadHTML("<html>$text</html>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$html = $doc->getElementsByTagName('html')[0];
remove_nodes_and_attributes($doc, $html, $allowed_tags, $allowed_attributes);
echo substr($doc->saveHTML(), 6, -8);
Вывод (для ваших примеров данных):
<img style="background:red">
<p>A function is triggered if an error occurs when loading the image. The function shows an alert box with a text. In this example we refer to an image that does not exist, therefore the onerror event occurs.</p>
Демонстрация на 3v4l.org