在PHP DOM中,在递归函数中获取元素/节点深度

时间:2014-01-11 18:23:00

标签: php dom recursion

我有以下函数,它通过递归调用自身将给定dom元素的所有子元素/文本节点读入数组。

它运行正常,但在发生任何递归之前,我需要与第一个(!)给定DOM节点相关的每个节点(文本或元素)的深度。我无法弄清楚如何做到这一点,任何想法?

function recursively_find_text_nodes($dom_element) {

    $return = array();

    foreach ($dom_element->childNodes as $dom_child) {

        switch ($dom_child->nodeType) {

            case XML_TEXT_NODE:

                if (trim($dom_child->nodeValue) !== '') {                

                    $return[] = $dom_child->nodeValue;

                }

            break;

            case XML_ELEMENT_NODE:

                $return = array_merge($return, $this->recursively_find_text_nodes($dom_child));

            break;

        }

    }

    return $return;

}

我正在使用此函数解析XML节点。它可以包含任意数量的元素和子元素。我的想法是每次函数进入递归时我都会输入一个深度变量。问题是,当我在一个实际上不会更深入的节点中,但是在树中,我必须-1变量。因此,对于我当前所处的每个节点,我需要关于在(!)之前传递给函数的DOM节点的当前元素的深度,它进入递归。

1 个答案:

答案 0 :(得分:3)

如果您提供了所需的输出,那么问题就会更加清晰。深度参数可以按如下方式传递:

function recursively_find_text_nodes($dom_element, $depth=1) {

    $return = array();

    foreach ($dom_element->childNodes as $dom_child) {

        switch ($dom_child->nodeType) {

            case XML_TEXT_NODE:
                if (trim($dom_child->nodeValue) !== '') {
                    $return[] = array (
                        'depth' => $depth, 
                        'value' => $dom_child->nodeValue
                    );
                }
                break;

            case XML_ELEMENT_NODE:
                $return[] = array (
                    'depth' => $depth,
                    'value' => $dom_child
                );

                $return = array_merge($return, $this->recursively_find_text_nodes($dom_child, $depth+1));
                break;
        }
    }

    return $return;
}

返回值可能不是您想要的,但您必须更加具体。


<强>更新

根据我的理解,你可能意味着这样的事情:

<?php

function recursively_find_text_nodes($dom_element, $depth=1, $predecessor_depth=0) {

    $return = array();

    foreach ($dom_element->childNodes as $dom_child) {

        switch ($dom_child->nodeType) {

            case XML_TEXT_NODE:
                if (trim($dom_child->nodeValue) !== '') {
                    $return[] = array (
                        'absolute_depth' => $depth,
                        'relative_depth' => $depth - $predecessor_depth,
                        'value' => $dom_child->nodeValue
                    );

                    $predecessor_depth = $depth;
                }
                break;

            case XML_ELEMENT_NODE:
                $return[] = array (
                    'absolute_depth' => $depth,
                    'relative_depth' => $depth - $predecessor_depth,
                    'value' => $dom_child
                );

                // Add the sub tree nodes to the result array
                $child_return_value = $this->recursively_find_text_nodes($dom_child, $depth+1, $predecessor_depth);
                $return = array_merge($return, $child_return_value);

                // Determine the depth of the last one processed
                $predecessor_depth = $return[count($return)-1]['absolute_depth'];

                break;
        }
    }

    return $return;
}

?>

如果它还是其他东西,你应该提供示例输入和输出(总是设计算法时的第一步。)