Search code examples
phpxmlforeachsimplexml

PHP SimpleXMLElement addChild in a Loop Only Showing Last Value


I'm trying to generate an XML file based on some data that I'm processing in a loop. My final XML output needs to look like this:

<Line>
  <Code>123</Code>
  <Description>Acme Constructions</Description>
  <TransactionAmount>44.00</TransactionAmount>
  <BaseCurrency>AUD</BaseCurrency>
</Line>
<Line>
  <Code>456</Code>
  <Description>Acme Flowers</Description>
  <TransactionAmount>23.00</TransactionAmount>
  <BaseCurrency>AUD</BaseCurrency>
</Line>
<Line>
  <Code>789</Code>
  <Description>General Hospital</Description>
  <TransactionAmount>19.00</TransactionAmount>
  <BaseCurrency>AUD</BaseCurrency>
</Line>

I'm looping through and using addChild to create a new child XML record but my final XML file is only showing the last value from the loop, not the previous ones. Here's my PHP code:

$xml = new SimpleXMLElement('<xml></xml>');

foreach ($invoiceLineItems->LineItem as $invoiceLineItem) {

    $description = $invoiceLineItem->Description;
    $amount = $invoiceLineItem->UnitAmount;
    $Code = $invoiceLineItem->AccountCode;

    $xml = $xml->addChild('Line');
    $xml->addChild('Code', $Code);
    $xml->addChild('Description', $description);
    $xml->addChild('Amount', $amount);

} 


// Save XML
$xml->asXML();

$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
$dom->save($fileName);

This generates the .xml file but it only has a single

<Line>
...
</Line> 

for the last record in the loop, not one for all records in the loop.


Solution

  • Because you updated value of $xml variable from the root element to the newly added child element here :

    $xml = $xml->addChild('Line');
    

    Use different variable to reference the newly added child element :

    $line = $xml->addChild('Line');
    $line->addChild('Code', $Code);
    $line->addChild('Description', $description);
    $line->addChild('Amount', $amount);
    

    Also, your expected final XML isn't well-formed, hence can't be generated normally using a proper XML parser. The root <xml> still needed to make an XML.