PHP-kod:
$data = array(/* En associativ array med arrays av massa stdclass-objekt */);
$firstCol = false;
$firstRow = true;
function handleNode(&$node,$data=null) {
global $firstRow,$firstCol,$data;
switch($node->nodeType) {
case XML_ELEMENT_NODE:
{
switch($node->tagName) {
case 'table:table-row':
$formula = $node->firstChild;
$m = array();
if (preg_match('/^for\s?each\s*\(\s*\$([a-z0-9_]+)\s+as\s+\$([a-z0-9_]+)\s*\)\s*(\{)?/i',$formula->textContent,$m))
{
$array = $m[1];
$iterator = $m[2];
if (array_key_exists($array,$data)) {
foreach ($data[$array] as $row) {
$newNode = $node->cloneNode();
foreach ($newNode->childNodes as $childNode)
handleNode($childNode,$row);
$node->insertBefore($newNode,$node->nextSibling);
}
$node->parentNode->removeChild($node);
}
else {
$node->parentNode->removeChild($node);
return;
}
}
$firstCol = true;
break;
case 'table:table-cell':
if (!$firstCol) {
$m = array();
if (preg_match('/^\$([a-z0-9_]+)\s*->\s*\$([a-z0-9_]+)/i',$node->textContent,$m))
{
$node->textContent = preg_replace('/^\$([a-z0-9_]+)\s*->\s*\$([a-z0-9_]+)/ie','@$data->\\2');
}
}
break;
}
echo $node->tagName."\n";
foreach ($node->childNodes as $childNode)
handleNode($childNode);
switch($node->tagName) {
case 'table:table-row':
$firstRow = false;
break;
case 'table:table-cell':
$firstCol=false;
break;
}
}
break;
case XML_TEXT_NODE:
echo "\"$node->textContent\"\n";
break;
}
}
Min XML ser egentligen ut så här (bara det viktigaste):
Kod:
...
<table:table-row>
<table:table-cell>
<text:p>foreach ($receipts as $receipt) {</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->id</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->name</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->amount</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->vat1</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->vat2</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->vat3</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->net</text:p>
</table:table-cell>
<table:table-cell>
<text:p>$receipt->date</text:p>
</table:table-cell>
<table:table-cell/>
</table:table-row>
...mer XML...
Notera
foreach som står i första cellen, den matchas i en preg_match, och sedan klonas raden lika många gånger som det finns värden i arrayen.
Jag tror att problemet ligger i foreach ($node->childNodes) eftersom den tar en ögonblicksbild av barnen och loopar dem, och tar inte hänsyn till ändringar.
Hur kan man tänka på annat sätt?