alejnavab
alejnavab

Reputation: 1212

Convert the following basic XML document in a two dimensional PHP array

I have the following XML document,

<?xml version="1.0" encoding="UTF-8"?>
<messages>
  <message>
    <from>Person 1</from>
    <to>Person 2</to>
    <platform>Instagram Direct Messaging</platform>
    <date>2016/06/27</date>
    <time>12:00</time>
    <ampm>PM</ampm>
    <specialcontent>none</specialcontent>
    <content>Hello</content>
  </message>
  <message>
    <from>Person 1</from>
    <to>Person 2</to>
    <platform>Instagram Direct Messaging</platform>
    <date>2016/06/27</date>
    <time>12:00</time>
    <ampm>PM</ampm>
    <specialcontent>none</specialcontent>
    <content>How are you?</content>
  </message>
  <message>
    <from>Person 2</from>
    <to>Person 1</to>
    <platform>Instagram Direct Messaging</platform>
    <date>2017/06/27</date>
    <time>6:00</time>
    <ampm>PM</ampm>
    <specialcontent>none</specialcontent>
    <content>Oh, hey there. I'm fine</content>
  </message>
  <message>
    <from>Person 2</from>
    <to>Person 1</to>
    <platform>Instagram Direct Messaging</platform>
    <date>2017/06/27</date>
    <time>6:01</time>
    <ampm>PM</ampm>
    <specialcontent>none</specialcontent>
    <content>What about you?</content>
  </message>
</messages>

And I'd like to convert it to a PHP array named $MessagesArray that looks like this (assuming I use print_r ($PeopleList); to display the array):

Array (
    [0] => Array (
            [from] => Person 1
            [to] => Person 2
            [platform] => Instagram Direct Messaging
            [date] => 2016/06/27
            [time] => 12:00
            [ampm] => PM
            [specialcontent] => none
            [content] => Hello
     )
    [1] => Array (
            [from] => Person 1
            [to] => Person 2
            [platform] => Instagram Direct Messaging
            [date] => 2016/06/27
            [time] => 12:00
            [ampm] => PM
            [specialcontent] => none
            [content] => How are you?
     )
    [2] => Array (
            [from] => Person 2
            [to] => Person 1
            [platform] => Instagram Direct Messaging
            [date] => 2016/06/27
            [time] => 6:00
            [ampm] => PM
            [specialcontent] => none
            [content] => Oh, hey there. I'm fine
     )
    [3] => Array (
            [from] => Person 2
            [to] => Person 1
            [platform] => Instagram Direct Messaging
            [date] => 2016/06/27
            [time] => 6:01
            [ampm] => PM
            [specialcontent] => none
            [content] => What about you?
     )
)

So, as you can see, it is a multidimensional array, where the main array is indexed and the inner arrays are assosiative. Note that the main array has an inner array for each <message> XML element in the XML document, and also note that at the same time each inner array has a key/value pair for each <message> child, where the child name is assigned to the key and the inner HTML is assigned to the value.

I can manually create the previous array using the following code:

$MessagesArray = array(
    array(
        "from" => "Person 1",
        "to" => "Person 2",
        "platform" => "Instagram Direct Messaging",
        "date" => "2016/06/27",
        "time" => "12:00",
        "ampm" => "PM",
        "specialcontent" => "none",
        "content" => "Hello"
    ),
    array(
        "from" => "Person 1",
        "to" => "Person 2",
        "platform" => "Instagram Direct Messaging",
        "date" => "2016/06/27",
        "time" => "12:00",
        "ampm" => "PM",
        "specialcontent" => "none",
        "content" => "How are you?"
    ),
    array(
        "from" => "Person 2",
        "to" => "Person 1",
        "platform" => "Instagram Direct Messaging",
        "date" => "2016/06/27",
        "time" => "6:00",
        "ampm" => "PM",
        "specialcontent" => "none",
        "content" => "Oh, hey there. I'm fine"
    ),
    array(
        "from" => "Person 2",
        "to" => "Person 1",
        "platform" => "Instagram Direct Messaging",
        "date" => "2016/06/27",
        "time" => "6:01",
        "ampm" => "PM",
        "specialcontent" => "none",
        "content" => "What about you?"
    )
);

However, I'd like to create it automatically. How can I do that? I know I have to use nested foreach functions, perhaps twice, but I can't figure out how.


Edit

The code I have at the moment,

$messagesXML = simplexml_load_file("assets/xml/messages.xml") or die("Server-side error: Cannot create object.");
$MessagesArray = array();
foreach ($messagesXML as $message) {
    $TemporalArrayOfCurrentMessage = array();
    foreach ($message as $key => $value ) {
        $TemporalArrayOfCurrentMessage[$key] = $value;
    }
    $MessagesArray[] = $TemporalArrayOfCurrentMessage;
}
print_r ($MessagesArray);

isn't working, although it's very close, because it is returning:

Array (
    [0] => Array (
        [from] => SimpleXMLElement Object ( [0] => Person 1 )
        [to] => SimpleXMLElement Object ( [0] => Person 2 )
        [platform] => SimpleXMLElement Object ( [0] => Instagram Direct Messaging )
        [date] => SimpleXMLElement Object ( [0] => 2016/06/27 )
        [time] => SimpleXMLElement Object ( [0] => 12:00 )
        [ampm] => SimpleXMLElement Object ( [0] => PM )
        [specialcontent] => SimpleXMLElement Object ( [0] => none )
        [content] => SimpleXMLElement Object ( [0] => Hello )
    )
    [1] => Array (
        [from] => SimpleXMLElement Object ( [0] => Person 1 )
        [to] => SimpleXMLElement Object ( [0] => Person 2 )
        [platform] => SimpleXMLElement Object ( [0] => Instagram Direct Messaging )
        [date] => SimpleXMLElement Object ( [0] => 2016/06/27 )
        [time] => SimpleXMLElement Object ( [0] => 12:00 )
        [ampm] => SimpleXMLElement Object ( [0] => PM )
        [specialcontent] => SimpleXMLElement Object ( [0] => none )
        [content] => SimpleXMLElement Object ( [0] => How are you? )
    )
    [2] => Array (
        [from] => SimpleXMLElement Object ( [0] => Person 2 )
        [to] => SimpleXMLElement Object ( [0] => Person 1 )
        [platform] => SimpleXMLElement Object ( [0] => Instagram Direct Messaging ) [date] => SimpleXMLElement Object ( [0] => 2016/06/27 )
        [time] => SimpleXMLElement Object ( [0] => 6:00 )
        [ampm] => SimpleXMLElement Object ( [0] => PM )
        [specialcontent] => SimpleXMLElement Object ( [0] => none )
        [content] => SimpleXMLElement Object ( [0] => Oh, hey there. I'm fine )
    )
    [3] => Array (
        [from] => SimpleXMLElement Object ( [0] => Person 2 )
        [to] => SimpleXMLElement Object ( [0] => Person 1 )
        [platform] => SimpleXMLElement Object ( [0] => Instagram Direct Messaging )
        [date] => SimpleXMLElement Object ( [0] => 2016/06/27 )
        [time] => SimpleXMLElement Object ( [0] => 6:01 ) [ampm] => SimpleXMLElement Object ( [0] => PM )
        [specialcontent] => SimpleXMLElement Object ( [0] => none )
        [content] => SimpleXMLElement Object ( [0] => What about you? )
    )
) 

Upvotes: 0

Views: 61

Answers (3)

alejnavab
alejnavab

Reputation: 1212

OK, so after trying I finally could solve it myself. The code is:

$messagesXML = simplexml_load_file("assets/xml/messages.xml") or die("Server-side error: Cannot create object.");
$MessagesArray = array();
$TemporalArrayOfCurrentMessage = array();
foreach ($messagesXML as $message) {
    foreach ($message as $key => $value ) {
        $TemporalArrayOfCurrentMessage[$key] = $value->__toString();
    }
    $MessagesArray[] = $TemporalArrayOfCurrentMessage;
}
echo "<h1>Automatic array</h1>";
print_r ($MessagesArray);

Upvotes: 0

ThW
ThW

Reputation: 19512

I would not consider this a conversion, it is basic XML reading. You can do this with DOM+XPath:

$document = new DOMDocument();
$document->loadXml($xmlString);
$xpath = new DOMXpath($document);

$data = [];
foreach ($xpath->evaluate('/messages/message') as $message) {
    $data[] = [
        'from' => $xpath->evaluate('string(from)', $message),
        'to' => $xpath->evaluate('string(to)', $message),
        'platform' => $xpath->evaluate('string(platform)', $message),
        'date' => $xpath->evaluate('string(date)', $message),
        'time' => $xpath->evaluate('string(time)', $message),  
        'ampm' => $xpath->evaluate('string(ampm)', $message),  
        'specialcontent' => $xpath->evaluate('string(specialcontent)', $message),  
        'content' => $xpath->evaluate('string(content)', $message),  
    ];
}

var_dump($data);

Xpath expressions like string(from) will return an empty string if the node can not be found.

HINT: You should avoid trying to read the array keys from the XML. This could lead to missing keys in the array if the XML changes.

Upvotes: 0

Christian Diehl
Christian Diehl

Reputation: 11

Try this one

$xmlstring = file_get_contents("messages.xml"); //the XML file
$xml = simplexml_load_string($xmlstring);
$xml = json_decode(json_encode($xml));

$counter = 0;
foreach($xml as $message) {
    $MessagesArray[$counter] = $message;
    $counter++;
}

foreach($MessagesArray as $messages) {
    foreach($messages as $message) {
        echo 'from: '.$message->from.'<br>';
        echo 'to: '.$message->to.'<br>';
        echo 'platform: '.$message->platform.'<br>';
        echo 'date: '.$message->date.'<br>';
        echo 'time: '.$message->time.'<br>';
        echo 'am/pm: '.$message->ampm.'<br>';
        echo 'special content: '.$message->specialcontent.'<br>';
        echo 'content: '.$message->content.'<br><br>';
    }
}

Hope it helps =)

Upvotes: 1

Related Questions