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.