PHP排序DOM元素和替换

时间:2016-08-15 18:20:07

标签: php dom xpath

我目前有一个如下所示的ul列表:

<ul id="primary-nav">
    <li class="navButton" id="amps_off_button" data-order="6">
        <span class="navButton-color red"><p>AMPS Off</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="amps_alarms" data-order="7">
        <span class="navButton-color"><p>AMPS Alarms</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="sysConfig" data-order="3">
        <span class="navButton-color"><p>System Configuration</p></span>
        <span class="glare"></span></li>
    <li class="navButton" id="system" data-order="4">
        <span class="navButton-color"><p>System</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="backBtn" data-order="100">
        <span class="navButton-color"><p>BACK</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="rescan" data-order="101">
        <span class="navButton-color"><p>ReScan</p></span>
        <span class="glare"></span>
    </li>
</ul>

在我的Navigation类中,我有一个可以调用的函数,它将按数据顺序中的值对无序列表的顺序进行排序:

public function setOrder() {
    $liNodeList = $this->xpath->query("//ul[@id='primary-nav']//li");
    $liNodes = iterator_to_array($liNodeList);

    usort($liNodes, array('Navigation', 'sortListByOrderAttr'));

    if ($liNodeList->length == count($liNodes)) {
        for ($i = 0; $i < $liNodeList->length; $i++) {
            $node = $liNodeList->item($i);
            $newNode = $liNodes[$i];
            $node->parentNode->replaceChild($newNode, $node);
        }
    }
    else echo "error";
}

private static function sortListByOrderAttr($a, $b) {
    return (int) $a->getAttribute('data-order') - (int) $b->getAttribute('data-order');
}

出于某种原因,我没有得到列表的正确顺序。相反,输出显示4个项目,而不是它应该显示的6个项目:

<ul id="primary-nav">
    <li class="navButton" id="amps_off_button" data-order="6">
        <span class="navButton-color red"><p>AMPS Off</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="amps_alarms" data-order="7">
        <span class="navButton-color"><p>AMPS Alarms</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="backBtn" data-order="100">
        <span class="navButton-color"><p>BACK</p></span>
        <span class="glare"></span>
    </li>
    <li class="navButton" id="rescan" data-order="101">
        <span class="navButton-color"><p>ReScan</p></span>
        <span class="glare"></span>
    </li>
</ul>

我怀疑我的问题是我的$node->parentNode->replaceChild($newNode, $node);不是es bueno。也许我需要一种不同的方法来对此进行排序?帮助赞赏!

1 个答案:

答案 0 :(得分:0)

好吧,在考虑了cHao所说的内容后,似乎在重新阅读了replaceChild的工作原理后,它解释了为什么我的方法没有产生正确的结果,因为新的子节点已经存在于节点集。

我已经修改了代码:

public function setOrder() {
    $liNodeList = $this->xpath->query("//ul[@id='primary-nav']//li");
    $liNodes = iterator_to_array($liNodeList);

    usort($liNodes, array('Navigation', 'sortListByOrderAttr'));

    if ($liNodeList->length == count($liNodes)) {
        for ($i = 0; $i < $liNodeList->length; $i++) {
            $node = $liNodeList->item($i);
            $newNode = $this->doc->importNode($liNodes[$i], TRUE);
            $node->parentNode->appendChild($newNode);
        }
    }
    else echo "error with nav menu";
}