0

Trying to import an sms log into php for parsing in a mysql db. Unable to parse individual array values past grabbing the full array of all records.

File loads, able to print array of entire input successfully, but foreach loop returns only one result, not all 13, and is empty.

// Load xml file else check connection
$xml = simplexml_load_file("input.xml") or die("Error: Cannot load file");
$con = json_encode($xml);
$newXML = json_decode($con, true);

print_r($newXML['sms']); //Output: Prints 0-4 lines successfully all together in array

foreach ($newXML['sms'] as $attrib) {
    
    $date = $attrib->date;
    $body = $attrib->body;
    echo $date . " - " . $body; // test output (fails and returns empty)

//Save Each Separate array line (sms message record) info to Db...
...

XML File layout:

<?xml version="1.0" encoding="UTF-8"?>
<smsgroup>
    <sms address="1234567" time="Apr 30, 2022 1:00:00 PM" date="1555987654339" type="2" body="message 5" read="1" />
    <sms address="1234567" time="Apr 30, 2022 1:00:00 PM" date="1555987654333" type="1" body="sms 4" read="1" />
    <sms address="5555555" time="Apr 30, 2022 1:00:00 PM" date="1555987654329" type="1" body="another message 3" read="1" />
    <sms address="5555555" time="Apr 30, 2022 1:00:00 PM" date="1555987654324" type="1" body="message 2" read="1" />
    <sms address="1234567" time="Apr 30, 2022 1:00:00 PM" date="1555987654321" type="2" body="message 1" read="1" />
</smsgroup>

3 Answers 3

2

Try this:

foreach ($newXML['sms'] as $attrib) {
    $date = $attrib["@attributes"]["date"];
    $body = $attrib["@attributes"]["body"];
    echo $date . " - " . $body; 
}
Sign up to request clarification or add additional context in comments.

1 Comment

Wow. I had not realized @attributes had to be used as well in the code. Thank you so much! Solved.
1

Consider directly importing that relatively flat, attribute-centric XML into MySQL table using LOAD XML. Below can be run as any other SQL command from PHP.

Assuming all attribute names match table names (though unmatched names are ignored):

LOAD XML LOCAL INFILE 'input.xml' 
  INTO TABLE myTable 
  ROWS IDENTIFIED BY '<sms>';

Alternatively, use local variables with SET for specific columns or differently named table names:

LOAD XML LOCAL INFILE 'input.xml'
  INTO TABLE myTable (@date, @body) 
  ROWS IDENTIFIED BY '<sms>'
  SET date_column=@date, body_column=@body; 

Comments

1

You can simplify your code by using SimpleXML properly and not having to json encode and decode the data...

Use -> to access the elements and [] to access the attributes.

$xml = simplexml_load_file('input.xml') or die('Error: Cannot load file');

foreach ($xml->sms as $attrib) {
    $date = $attrib['date'];
    $body = $attrib['body'];
    echo $date . ' - ' . $body; // test output (fails and returns empty)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.