Home > Net >  Converting XML to Array, and then looping through some objects results in 'Illegal string offse
Converting XML to Array, and then looping through some objects results in 'Illegal string offse

Time:02-16

Before this gets marked as a duplicate, please know that my issue is slightly different to the normal Illegal string offset issue.

I have some XML which is an order dispatch notification. I convert to it to JSON and then to an array. Then I loop through the line items and add them to a MySQL database.

This works great when there are multiple items to loop through. When there is just 1 item, it returns the Illegal string offset error.

I've rewrote the code to simulate the issue here:

echo "SINGLE ITEM: \r\n";
$xmlstring = '<dispatch_notification>' .
        '    <line_items>' .
        '            <sku>N123456789</sku>' .
        '            <barcode></barcode>' .
        '            <quantity>1</quantity>' .
        '    </line_items>' .
        '</dispatch_notification>' .
        '';
processXML($xmlstring);


echo "\r\n\r\nMULTIPLE ITEMS: \r\n";
$xmlstring = '<dispatch_notification>' .
        '    <line_items>' .
        '            <sku>N123456789</sku>' .
        '            <barcode></barcode>' .
        '            <quantity>1</quantity>' .
        '    </line_items>' .
        '    <line_items>' .
        '            <sku>O123456789</sku>' .
        '            <barcode></barcode>' .
        '            <quantity>5</quantity>' .
        '    </line_items>' .
        '</dispatch_notification>' .
        '';
processXML($xmlstring);

function processXML($xmlstring) {
    $xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
    $dispatchedOrder = json_decode(json_encode($xml), TRUE);
    foreach ($dispatchedOrder['line_items'] as $item) {//loop through each line item
        echo $item['sku'] . ", " . $item['quantity'] . "\r\n";
    }
}

This outputs:

SINGLE ITEM: Warning: Illegal string offset 'sku' in /testing/xmltest.php on line 47

Warning: Illegal string offset 'quantity' in /testing/xmltest.php on line 47 N, N , Warning: Illegal string offset 'sku' in /testing/xmltest.php on line 47

Warning: Illegal string offset 'quantity' in /testing/xmltest.php on line 47 1, 1

MULTIPLE ITEMS: N123456789, 1 O123456789, 5

This shows that it worked fine when looping through the line_items object when there are multiple but not a single one.

I also tried the XML in this format but this had the same issue.

<line_items>
    <item>
        <sku>M7389462334</sku>
        <barcode></barcode>
        <quantity>1</quantity>
    </item>
    <item>
        <sku>L67858745445</sku>
        <barcode></barcode>
        <quantity>1</quantity>
    </item>
</line_items>

I'm a bit stumped as to why this is happening, I don't often work with XML, usually JSON so I'm not sure if this is to do with the formatting of the XML or something else.

CodePudding user response:

I have some XML ... I convert to it to JSON and then to an array.

Don't do that. XML, JSON, and PHP arrays all have different ideas about how data can and should be structured. Blindly converting between them is just a bad idea.

Instead, look at the usage examples for SimpleXML and see how easy it makes it to work with XML.

Here is a working version of your code:

function processXML($xmlstring) {
    $xml = simplexml_load_string($xmlstring);
    foreach ($xml->line_items as $item) {
        echo $item->sku . ", " . $item->quantity . "\r\n";
    }
}

Note that I've got rid of the "LIBXML_NOCDATA" option as well - it's frequently misused due to a misunderstanding of how SimpleXML works, and a quirk in its debug output.

  • Related