parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Цикл по xml-документу

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

  • Цикл по xml-документу, Givi 09.07.2003 17:45 / 09.07.2003 17:52