| Новости | 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[]
}А, ну да, у каждой ноды должен быть уникальный айдишник...