多姆;PHP:如何包装一堆<;李>;内部<;ul>;

多姆;PHP:如何包装一堆<;李>;内部<;ul>;,php,domdocument,domxpath,dom-traversal,Php,Domdocument,Domxpath,Dom Traversal,我有一个html文档,带有不太好的标记,没有“ul”: <p>Lorem</p> <p>Ipsum...</p> <li class='item'>...</li> <li class='item'>...</li> <li class='item'>...</li> <div>...</div> 这是你需要的。您可能需要为真正的HTML调整XPath

我有一个html文档,带有不太好的标记,没有“ul”:

<p>Lorem</p>
<p>Ipsum...</p>
<li class='item'>...</li>
<li class='item'>...</li>
<li class='item'>...</li>
<div>...</div>

这是你需要的。您可能需要为真正的HTML调整XPath查询

$document = new DOMDocument;

// We don't want to bother with white spaces
$document->preserveWhiteSpace = false;

$html = <<<EOT
<p>Lorem</p>
<p>Ipsum...</p>
<li class='item'>...</li>
<li class='item'>...</li>
<li class='item'>last...</li>
<div>...</div>
EOT;

$document->LoadHtml($html);

$xpath = new DOMXPath($document);

$elements =  $xpath->query('//li[@class="item"]');

// Saves a reference to the Node that is positioned right after our li's
$ref = $xpath->query('//li[@class="item"][last()]')->item(0)->nextSibling;

$wrapper = $document->createElement('ul');
foreach($elements as $child) {
    $wrapper->appendChild($child);
} 

$ref->parentNode->insertBefore($wrapper, $ref);

echo $document->saveHTML();
$document=新文档;
//我们不想为空白而烦恼
$document->preserveWhiteSpace=false;

$html=也许您可以获取第一个
  • 父节点
    ,然后使用
    insertBefore
    方法:

    $html = <<<HTML
    <p>Lorem</p>
    <p>Ipsum...</p>
    <li class='item'>...</li>
    <li class='item'>...</li>
    <li class='item'>...</li>
    <div>...</div>
    HTML;
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    
    $xpath = new DOMXpath($doc);
    
    $elements = $xpath->query('//li[@class="item"]');
    
    $wrapper = $doc->createElement('ul');
    $elements->item(0)->parentNode->insertBefore(
        $wrapper, $elements->item(0)
    );
    
    foreach($elements as $child) {
        $wrapper->appendChild($child);
    }
    
    echo $doc->saveHTML();
    
    $html=createElement('ul');
    $elements->item(0)->parentNode->insertBefore(
    $wrapper,$elements->item(0)
    );
    foreach($child形式的元素){
    $wrapper->appendChild($child);
    }
    echo$doc->saveHTML();
    

    不确定如何将ul放在正确的位置-我想这正是我的问题。对不起,伙计,我没有机会确切知道li之前的元素是哪个,就像您的示例中的$div=$xpath->query('//div')->item(0);正如我所说,不知道你的文档会让你很难给出答案。您可以调整此部分以执行以下操作:
    $xpath->query('//li[last()')->item(0)->next_sibling()
    ;谢谢是的,我忘了提到这些李的可以在一个非特定的地方,即使他们都跟随对方。您建议的修复程序给了我一个“在null上调用next_sibling()的成员函数”,可能是因为我已经删除了li,而没有将它们放回,因此没有li,对吗?我更新了答案。你现在应该没事了<代码>$ref=$xpath->query('//li[@class=“item”][last()])->item(0)->nextSibling就我所描述的而言,它工作得非常完美。同样,li包含带有属性的a标签(href)-它们消失了(a标签和属性)。知道如何保存它们吗?
    $html = <<<HTML
    <p>Lorem</p>
    <p>Ipsum...</p>
    <li class='item'>...</li>
    <li class='item'>...</li>
    <li class='item'>...</li>
    <div>...</div>
    HTML;
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    
    $xpath = new DOMXpath($doc);
    
    $elements = $xpath->query('//li[@class="item"]');
    
    $wrapper = $doc->createElement('ul');
    $elements->item(0)->parentNode->insertBefore(
        $wrapper, $elements->item(0)
    );
    
    foreach($elements as $child) {
        $wrapper->appendChild($child);
    }
    
    echo $doc->saveHTML();