2014-01-11 2 views
1

У меня есть следующая функция, которая считывает все дочерние элементы/текстовые узлы данного элемента dom в массив, путем рекурсивного вызова.В PHP 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 с помощью этой функции. Он может иметь любое количество элементов и подэлементов. Идея состоит в том, что I +1 - переменная глубины, каждый раз, когда функция переходит в рекурсию. проблема в том, что когда я нахожусь в узле, который на самом деле не идет глубже, но в дереве мне придется -1 переменную. Поэтому для каждого узла, в котором я сейчас находится, мне понадобится глубина текущего элемента в отношении узла DOM, который был передан функции перед (!), Который перешел в рекурсию.

ответ

2

Вопрос будет намного яснее, если вы предоставили требуемый результат. Параметр глубины может быть передан следующим образом:

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; 
} 

?> 

Если еще что-то еще, вы должны предоставить пример ввода и вывода (всегда первый шаг при разработке алгоритма.)

+0

Спасибо, это действительно не то, что я намеревался. Я обновил свой вопрос, чтобы лучше объяснить, что я имел в виду. – Sebastian

+0

Ответ был обновлен. – wkampmann

Смежные вопросы