PHP: Преобразование <ul> <li> Тег дерева HTML в массив

Я использую jsTree, и мне нужно преобразовать этот код дерева тегов HTML <ul> <li> в массив PHP. Тег jsTree HTML будет передан в PHP для анализа и хранения в структурированном дереве PHP-массиве (см. Ниже структуру массива PHP).

Дополнительный вопрос : Является ли желаемая структура массива PHP хорошей или вы можете предложить хорошую структуру? Я открыт для предложений.

Заранее спасибо 🙂

Приветствия, Марк

Скриншот jsTree :

alt text

Строка дерева HTML :

 <ul class="ltr"> <li id="phtml_1" class=" open"> <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 1</a> <ul> <li class="leaf" id="phtml_2"> <a style="" class=" " href="#"><ins>&nbsp;</ins>Child 1.1</a> </li> <li class="open" id="phtml_3"> <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 1.1</a> <ul> <li class="leaf last" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.1.1</a> </li> </ul> </li> <li class="last open" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Folder 1.2</a> <ul> <li class="leaf" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.2.1</a> </li> <li class="leaf last" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.2.2</a> </li> </ul> </li> </ul> </li> <li id="phtml_5" class="file open"> <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 2</a> <ul> <li class="leaf" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Child 2.1</a> </li> <li class="leaf last" rel="default"> <a href="" style="" class="clicked"><ins>&nbsp;</ins>Child 2.2</a> </li> </ul> </li> <li class="leaf last" rel="default"> <a href="" style="" class=" "><ins>&nbsp;</ins>Outer Child</a> </li> </ul> 

Структура массива PHP :

 <?php $tree_array = array( 'Folder 1' => array( 'Child 1.1', 'Folder 1.1' => array( 'Child 1.1.1' ), 'Folder 1.2' => array( 'Child 1.2.1', 'Child 1.2.2' ), ), 'Folder 2' => array( 'Child 2.1', 'Child 2.2' ), 'Outer Child' ); echo '<pre>',print_r($tree_array),'</pre>'; ?> 

PHP print_r Выход :

 Array ( [Folder 1] => Array ( [0] => Child 1.1 [Folder 1.1] => Array ( [0] => Child 1.1.1 ) [Folder 1.2] => Array ( [0] => Child 1.2.1 [1] => Child 1.2.2 ) ) [Folder 2] => Array ( [0] => Child 2.1 [1] => Child 2.2 ) [0] => Outer Child ) 

Что касается:

Моя проблема: мне сложно анализировать тег HTML и сохранять его в массиве PHP.

Я предлагаю вам использовать парсер HTML, например simplehtmldom . Это позволит вам перемещаться по HTML DOM так, как вы хотите.

Вот быстрый и грязный скрипт для UL:

 <?php require_once( "simplehtmldom/simple_html_dom.php" ); $DOM = file_get_html( "test.htm" ); $ARR = array( ); function WalkUL( $ul, &$ar ) { foreach( $ul->children as $li ) { if ( $li->tag != "li" ) { continue; } $arar = array( ); foreach( $li->children as $ulul ) { if ( $ulul->tag != "ul" ) { continue; } WalkUL( $ulul, $arar ); } $ar[ $li->find( "a", 0 )->plaintext ] = $arar; } } WalkUL( $DOM->find( "ul", 0 ), $ARR ); print_r( $ARR ); ?> 

Его выход не совсем так, как вам хотелось, но близко:

 Array ( [Folder 1] => Array ( [Child 1.1] => Array ( ) [Folder 1.1] => Array ( [Child 1.1.1] => Array ( ) ) [Folder 1.2] => Array ( [Child 1.2.1] => Array ( ) [Child 1.2.2] => Array ( ) ) ) [Folder 2] => Array ( [Child 2.1] => Array ( ) [Child 2.2] => Array ( ) ) [Outer Child] => Array ( ) ) 

Вместо того, чтобы возиться с html, вы должны представить данные дерева в более удобном для программиста формате.

 $('#saveButton').click(function() { var treeData = $.tree.reference($('#sortableTree')).get(undefined, 'json'); var tmp = serializeTree(treeData, 0); // now json-encode tmp and submit it }); function serializeTree(nodes, parent) { var parents = {}; var childOrder = [] var childOrders = {}; for(var i = 0; i < nodes.length; i++) { var node = nodes[i]; var id = node.attributes.id.substr(5); // assuming the id looks like 'abcd-ID' parents[id] = parent; childOrder.push(id); if(node.children) { var tmp = serializeTree(node.children, id); for(var id in tmp[0]) parents[id] = tmp[0][id]; for(var id in tmp[1]) childOrders[id] = tmp[1][id] } } childOrders[parent] = childOrder; return [parents, childOrders]; } 

Просто для референции: есть также плагин jQuery для сериализации дерева DOM HTML в списках <ol> и <ul>: http://www.drakedata.com/serializetree/sampleTree.html – он преобразует вложенную структуру <ol> и <ul> перечисляет строку, которая может использоваться как связанный массив php.

Если у вас есть UL, который не содержит каких-либо элементов href (например, просто текст, следующий ul). Я скорректировал код Simplehtmldom Salman для работы с этим:

 $DOM = str_get_html( $catshtml ); $ARR = array( ); function WalkUL( $ul, &$ar ) { foreach( $ul->children as $li ) { if ( $li->tag != "li" ) { continue; } $arar = array( ); foreach( $li->children as $ulul ) { if ( $ulul->tag != "ul" ) { continue; } WalkUL( $ulul, $arar ); } $ar[ trim(preg_replace("#</?[az]+[^>]*>(.+</[az]+[^>]*>|)#is","",$li->innertext)) ] = $arar; } } WalkUL( $DOM->find( "ul", 0 ), $ARR ); echo "<pre>"; print_r( $ARR );