Я реализую парсер PHP sitemap из файла XML. Я делаю относительно хорошо. Тем не менее, мне нужно, чтобы синтаксический анализатор был более динамичным. Мне нужно реализовать рекурсивную функцию, которая будет продолжать цикл для каждого найденного дочернего_нода. Узел может содержать много дочерних_кодов внутри другого дочернего_нода. То, что я делал до сих пор, заключалось в том, чтобы реализовать отдельный цикл foreach с разными именами переменных для каждого child_node, однако это неприемлемо, поскольку оно не является настолько гибким.
Это мой xml-файл:
<sitemap> <node> <id>rootnode</id> <link>home.html</link> </node> <node> <id>about</id> <link>about.html</link> </node> <node> <id>contact</id> <link>contact.html</link> <child_node> <id>contact_uk</id> <link>contact_uk.html</link> <child_node> <id>customer_support_uk</id> <link>customer_support_uk.html</link> </child_node> </child_node> <child_node> <id>contact_usa</id> <link>contact_usa.html</link> </child_node> </node> <node> <id>products</id> <link>products.html</link> </node> </sitemap>
Вы можете заметить, что контакт узла имеет child_node в child_node. Здесь мне нужна рекурсивная функция.
Это мой текущий PHP-код:
$source = 'sitemap.xml'; // load as file $sitemap = simplexml_load_file($source, null, true); foreach ($sitemap->node as $node) { if ($node->child_node != "") { echo "$node->link<br/>"; foreach ($node->child_node as $child) { if ($child->child_node != "") { echo " " . $child->link . "<br/>"; foreach ($child->child_node as $innerchild) { echo " " . $innerchild->link . "<br/>"; } } else { echo " " . $child->link . "<br/>"; } } } else { echo "$node->link<br/>"; } }
У этого PHP есть правильный вывод, но я должен создать другой отдельный цикл foreach для каждого дочернего_каталога в своем родительском child_node. Может ли кто-нибудь указать мне в правильном направлении, как изменить свой PHP-код, чтобы пересечь каждый child_node в child_node, найденный в файле Sitemap?
Большое спасибо!
Не тестировалось … но должно работать:
function print_node($node, $level){ echo str_repeat("-",$level); echo "$node->link\n"; if ($node->child_node != "") { foreach ($node->child_node as $child) { print_node($child,$level+1); } } } $source = 'sitemap.xml'; $sitemap = simplexml_load_file($source, null, true); foreach ($sitemap->node as $node) print_node($node,0);
Вам понадобится рекурсивная функция и вызовите это при обработке каждого узла верхнего уровня.
function processChildren( $node ) { foreach( $node->child_node as $child ) { echo "$child->link<br/>"; if( count( $child->child_node ) ) { processChildren( $child ); } } }
Я оставлю в качестве интересного упражнения для читателя, как получить отступы. 😉