DiDOM :如何解开父节点并提升子节点?

DiDOM : How to unwrap a parent node and elevate the children?

提问人:scott8035 提问时间:7/11/2023 更新时间:7/11/2023 访问量:36

问:

我有一个关于 DiDOM HTML/XML DOM 解析包的问题。

我有以下示例 HTML:

<body>
    <div>
        <p>1</p>
        <p>2</p>
        <p>3</p>
    </div>
    <div>
        <p>4</p>
        <p>5</p>
        <p>6</p>
        <div>
            <p>7</p>
            <p>8</p>
            <p>9</p>
        </div>
    </div>
</body>

我想做的是通过将子节点重新定位为 div 父节点的直接后代并删除现在为空的节点来“解包”每个节点。我尝试使用下面的代码来执行此操作,但它仅适用于某些节点;在其他情况下,该元素没有父元素,因此您不能在不引发异常的情况下使用。<div><p><div>$taginsertSiblingBefore(...)

下面是调用所需函数的一些示例代码:

// Remove <div> tags with no attributes
$divTags = $doc->find( 'div' );
foreach ( $divTags as $divTag ) {
    removeElementKeepingChildren( $divTag );
}

...这是违规代码本身:

function removeElementKeepingChildren( Element $tag ) : void {
    // I'd like to avoid needing this check...but without it, certain $tags cause the exception
    if ( ! $tag->parent() ) {
        return;
    }

    // "Backup" the children
    $children = $tag->children();

    // Remove the children from the node to be removed
    $tag->removeChildren();

    foreach ( $children as $child ) {
        $tag->insertSiblingBefore( $child );
    }

    $tag->remove();
}

一定有更好的方法来做到这一点......建议?

php html dom

评论

0赞 CBroe 7/11/2023
DOM 树中每个不是根节点的节点都必须有一个父节点。如果您在那里遇到没有 div 节点的 div 节点 - 那么唯一合乎逻辑的解释是,该节点已经以某种方式已从文档中删除。我不知道该库的 find 方法是如何工作的,如果结果具有与从 JavaScript 中的 getElementsByTagName 等方法获得的实时 HTMLCollection 相同的“实时”属性。[...]
0赞 CBroe 7/11/2023
[...]如果是这样的话,那么在删除一些节点的同时循环节点很容易出现问题。在这种情况下,我通常发现最好使用循环以相反的顺序迭代它们 - 然后您可以根据需要删除遇到的任何节点。for

答: 暂无答案