Новости | FAQ | Авторы | Документация | В действии | Библиотека |
Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Givi 09.07.2003 17:45 / 09.07.2003 17:52
Вот, может пригодицца кому. На вход ему переменную, ноду и код. Переменная последовательно принимает значения всех нод родительской ноды, начиная с неё самой. Можно процесс прервать выставив stop(1). Памяти жрёт гораздо меньше чем рекурсия. Идея взята вот отсюда: http://parser2.parser.ru/forum/message_6743.html. Спасибо Luzhnikovskiy.@xLoop[name;node;code][firstNodeId;doCycle;xStack] $firstNodeId(^node.getAttribute[id]) $doCycle(1) $xStack[^hash::create[]] ^while($doCycle && !$caller.stop){ ^if($node is xnode){ ^if($node.nodeType==1){ $caller.$name[$node] $code ^if(^node.hasChildNodes[]){ ^__xPush[$node] $node[$node.firstChild] }{ ^if(^node.getAttribute[id]==$firstNodeId){ $node[] }{ $node[$node.nextSibling] } } }{ $node[$node.nextSibling] } }{ ^if($xStack>1){ $node[^__xPop[]] ^if(^node.getAttribute[id] eq '$firstNodeId'){ $doCycle(0) }{ $node[$node.nextSibling] } }{ $doCycle(0) } } } @__xPush[node][i;pushed] $i($caller.xStack) ^i.inc[] $pushed[ $.$i[$node] ] $caller.xStack[^caller.xStack.union[$pushed]] $result[] @__xPop[][i;node] $i($caller.xStack) ^if($i){ $node[$caller.xStack.$i] ^caller.xStack.delete[$i] $result[$node] }{ $result[] }А, ну да, у каждой ноды должен быть уникальный айдишник...