I'm looping through an xml document, and attempting to clone a node, increment all of the id and name fields, and append the cloned node to the original document. The problem occurs because I'm using getElementsByTagName('loop'), and the appended child is a <loop> element. So php continues to process the loop on the appended elements. What's the best way to avoid this?

XML example:

<?xml version="1.0" encoding="utf-8"?>
<form id="resume" name="resume" method="post" action="--self--">
    <fieldset legend="General Information">
        <loop start="2" end="10">
            <expand title="#_loop_ facility name/employer" id="_loop_" state="minus">
                <element label="Facility/employer name" id="name__loop_" name="name__loop_" type="text" size="35" break="after">
                    <regex>nonblank</regex>
                </element>
                <element label="Unit/floor/dept" id="unit__loop_" name="unit__loop_" type="text" size="35" break="after">
                    <regex>nonblank</regex>
                </element>
                <element label="Address" id="address__loop_" name="address__loop_" type="text" size="35" break="after">
                    <regex>nonblank</regex>
                </element>
            </expand>
        </loop>
    </fieldset>
</form>

PHP example:

function expandLoops() {
	/* 	find loop elements
		copy to a new element
		append increment value to all ids and names, plus header title, wherever _loop_ appears
		append new element to loop
		repeat for each increment
		in xslt, remove loop tags */

$loops = $this->xmlDoc->getElementsByTagName('loop');		
foreach ($loops as $loop) {				
	$start = $loop->getAttribute('start');
	$end = $loop->getAttribute('end');

	for ($i = $start; $i <= $end; $i++) {				
		$clone = $loop->cloneNode(true);				
		$clone->setAttribute('id', $i);

		foreach ($clone->getElementsByTagName('*') as $node) {
			$nodeName = $node->getAttribute('name');
			$nodeId = $node->getAttribute('id');
			$nodeTitle = $node->getAttribute('title');
			$nodeValue = $node->nodeValue;

			$nodeName = str_replace('_loop_', $i, $nodeName);
			$nodeId = str_replace('_loop_', $i, $nodeId);
			$nodeTitle = str_replace('_loop_', $i, $nodeTitle);

			if (!empty($nodeName)) $node->setAttribute('name', $nodeName);
			if (!empty($nodeId)) $node->setAttribute('id', $nodeId);
			if (!empty($nodeTitle)) $node->setAttribute('title', $nodeTitle);
		}

		$loop->parentNode->appendChild($clone);
	}			
	$loop->parentNode->removeChild($loop);
}
}

$this->xmlDoc is a DomDocument object.

    In case anyone is wondering, this is what I ended up doing...though there must be a more efficient way...

    	/* find <loop> elements and copy template the indicated number of times */
    	function expandLoops() {		
    		$loops = array();				// holds places in original doc for reimporting cloned loops
    		$iLoop = 0;						// increment for $loops[]
    		$cloneDoc = new DomDocument;	// clone doc for processing to prevent infinite loop
    
    	foreach ($this->xmlDoc->getElementsByTagName('loop') as $loop) {	
    
    		$loops[$iLoop] = $loop;
    
    		//create a root element to hold each set of loops in the clone doc
    		$cloneLoop = $cloneDoc->appendChild($cloneDoc->createElement('clone', ''));
    		$cloneLoop->setAttribute('xml:id', $iLoop);
    
    		//append the <loop> node to the <clone> node in the clone doc
    		$clone = $cloneLoop->appendChild($cloneDoc->importNode($loop, true));
    
    		//copy the <loop> template ($end - $start) times
    		$start = $clone->getAttribute('start');
    		$end = $clone->getAttribute('end');					
    		for ($i = $start; $i <= $end; $i++) {
    
    			//clone the orignal <loop> template
    			$cloneClone = $clone->cloneNode(true);				
    			$cloneClone->setAttribute('id', $i);
    
    			//step through all of the nodes, replacing _loop_ with the counter
    			foreach ($cloneClone->getElementsByTagName('*') as $node) {
    				$nodeName = $node->getAttribute('name');
    				$nodeId = $node->getAttribute('id');
    				$nodeTitle = $node->getAttribute('title');
    
    				$nodeName = str_replace('_loop_', $i, $nodeName);
    				$nodeId = str_replace('_loop_', $i, $nodeId);
    				$nodeTitle = str_replace('_loop_', $i, $nodeTitle);
    
    				if (!empty($nodeName)) $node->setAttribute('name', $nodeName);
    				if (!empty($nodeId)) $node->setAttribute('id', $nodeId);
    				if (!empty($nodeTitle)) $node->setAttribute('title', $nodeTitle);
    			}
    
    			//append this copy to the <loop> node
    			$cloneLoop->appendChild($cloneClone);
    		}
    
    		//remove the original <loop> template from the <clone> node
    		$cloneLoop->removeChild($clone);
    		$iLoop++;			
    	}
    
    	/* loop through cloned document's <clone> elements */
    	for ($i = 0; $i <= $iLoop - 1; $i++) {		
    		$cloneLoop = $cloneDoc->getElementById($i);
    
    		/* reattach the <loop> elements to original, using $loops[] array placeholders */
    		foreach ($cloneLoop->getElementsByTagName('loop') as $loop) {				
    			$loops[$i]->parentNode->appendChild($this->xmlDoc->importNode($loop, true));
    		}
    
    		$loops[$i]->parentNode->removeChild($loops[$i]); //remove template node	from original		
    	}
    
    	unset($cloneDoc);
    	unset($loops);		
    }
      Write a Reply...