如何使用 DOMDocument 将特定的顺序元素包装在单个容器中?

假设我有以下标记:


<h3 class="handorgel__header">

    <button class="handorgel__header__button">

        Books, Literature and Languages

    </button>

</h3>


<div class="handorgel__content">

    <div class="handorgel__content__inner">

        <p>Hello</p>

    </div>

</div>


<h3 class="handorgel__header">

    <button class="handorgel__header__button">

        Business and Consumer Information

    </button>

</h3>


<div class="handorgel__content">

    <div class="handorgel__content__inner">

        <p>World</p>

    </div>

</div>


<p>Some text in between</p>


<h3 class="handorgel__header">

    <button class="handorgel__header__button">

        Fine Arts and Music

    </button>

</h3>


<div class="handorgel__content">

    <div class="handorgel__content__inner">

        <p>Hello</p>

    </div>

</div>


<h3 class="handorgel__header">

    <button class="handorgel__header__button">

        Genealogy

    </button>

</h3>


<div class="handorgel__content">

    <div class="handorgel__content__inner">

        <p>World</p>

    </div>

</div>

我想包装每组.handorgel__*元素,以便它们包含在一个容器中<div class="handorgel">。


<div class="handorgel">


    <h3 class="handorgel__header">

        <button class="handorgel__header__button">

            Books, Literature and Languages

        </button>

    </h3>


    <div class="handorgel__content">

        <div class="handorgel__content__inner">

            <p>Hello</p>

        </div>

    </div>


    <h3 class="handorgel__header">

        <button class="handorgel__header__button">

            Business and Consumer Information

        </button>

    </h3>


    <div class="handorgel__content">

        <div class="handorgel__content__inner">

            <p>World</p>

        </div>

    </div>


</div>


<p>Some text in between</p>


<div class="handorgel">


    <h3 class="handorgel__header">

        <button class="handorgel__header__button">

            Fine Arts and Music

        </button>

    </h3>


每个组中可以有任意数量的元素,以及页面的任意数量的组。我怎样才能检测到这些组并适当地包装它们?我目前DOMDocument在这个项目中使用了很多东西,所以如果可能的话,我也想将它用于这个目的,除非有明显更好的方法。


慕标5832272
浏览 100回答 1
1回答

素胚勾勒不出你

经过一系列的反复试验,我自己设法让这个工作起来。并不像我想象的那么困难,DOMDocument 实际上负责一些删除逻辑本身。/**&nbsp;* Wrap handorgel groups in appropriate containers&nbsp;*&nbsp;* @param string $content&nbsp;*&nbsp;* @return string&nbsp;*/function gpl_wrap_handorgel_shortcodes(string $content): string {&nbsp; &nbsp; if (! is_admin() && $content) {&nbsp; &nbsp; &nbsp; &nbsp; $DOM = new DOMDocument();&nbsp; &nbsp; &nbsp; &nbsp; // disable errors to get around HTML5 warnings...&nbsp; &nbsp; &nbsp; &nbsp; libxml_use_internal_errors(true);&nbsp; &nbsp; &nbsp; &nbsp; // load in content&nbsp; &nbsp; &nbsp; &nbsp; $DOM->loadHTML(mb_convert_encoding("<html><body>{$content}</body></html>", "HTML-ENTITIES", "UTF-8"), LIBXML_HTML_NODEFDTD);&nbsp; &nbsp; &nbsp; &nbsp; // reset errors to get around HTML5 warnings...&nbsp; &nbsp; &nbsp; &nbsp; libxml_clear_errors();&nbsp; &nbsp; &nbsp; &nbsp; $body = $DOM->getElementsByTagName("body");&nbsp; &nbsp; &nbsp; &nbsp; $handorgels = [];&nbsp; &nbsp; &nbsp; &nbsp; $prev_class = "";&nbsp; &nbsp; &nbsp; &nbsp; foreach ($body[0]->childNodes as $element) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Ensure that only HTML nodes get checked/modified&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($element->nodeType == 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $current_class = $element->getAttribute("class");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Find any handorgel elements&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (preg_match("/handorgel__/", $current_class)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $group = array_key_last($handorgels);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* If the previous class didn't include `handorgel__`, create a new handorgel object&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (! preg_match("/handorgel__/", $prev_class)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $handorgels[] = [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "container" => $DOM->createElement("div"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "elements"&nbsp; => [],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Update `$group` to match the new container&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $group = array_key_last($handorgels);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Append the current element to the group to be moved after all sequential handorgel&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* elements are located for its group&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $handorgels[$group]["elements"][] = $element;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Update `$prev_class` to track where handorgel groups should begin and end&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $prev_class = $current_class;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Construct the grouped handorgels&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; if ($handorgels) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach ($handorgels as $group => $handorgel) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $handorgel["container"]->setAttribute("class", "handorgel");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach ($handorgel["elements"] as $key => $element) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Insert the container in the starting position for the group&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($key === 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $element->parentNode->insertBefore($handorgels[$group]["container"], $element);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $handorgel["container"]->appendChild($element);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Remove unneeded tags (inserted for parsing reasons)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; $content = remove_extra_tags($DOM); // custom function that removes html/body and outputs the DOMDocument as a string&nbsp; &nbsp; }&nbsp; &nbsp; return $content;}add_filter("the_content", "gpl_wrap_handorgel_shortcodes", 30, 1);
打开App,查看更多内容
随时随地看视频慕课网APP