Search code examples
phparrayssimplexml

SimpleXML to Array


I load some XML which produces a SimpleXML Object like so (only displaying one Object)

SimpleXMLElement Object
(
    [Jobs] => SimpleXMLElement Object
    (
        [Job] => Array
            (
                [0] => SimpleXMLElement Object
                (
                    [ID] => J000001
                    [Name] => Internal Time
                    [Description] => Use this job to record your internal and non-billable time for activities such as annual leave, sick leave, professional development, staff meetings etc
                    [Client] => SimpleXMLElement Object
                    (
                        [ID] => 8430219
                        [Name] => Fake Client
                    )

                    [ClientOrderNumber] => SimpleXMLElement Object
                    (
                    )

                    [State] => Planned
                    [StartDate] => 2016-03-21T00:00:00
                    [DueDate] => 2017-03-21T00:00:00
                    [InternalID] => 11442733
                    [Assigned] => SimpleXMLElement Object
                    (
                        [Staff] => SimpleXMLElement Object
                            (
                                [ID] => 344460
                                [Name] => Som Name
                            )
                    )
                )
            )
    )
)

What I would like to do is create an array of the client Name and client ID. So I am aiming for something like so

[data] => array (
    8430219 => Fake Client,
    8430343 => Another Client,
    etc
)

At the moment, I can get the name in place, but struggling with the id because it says it is an illegal offset type. This is what I have

foreach($oXML->Jobs as $oEntry) {
    foreach ($oEntry->Job as $data) {
        $jobsArray = array(
            $data->Client->ID => $data->Client->Name
        );
    }
}

How can I create the array based on the SimpleXML Object I have?

Thanks


Solution

  • First of all, to obtain your desired array you can not use this syntax:

    $jobsArray = array( $key => $val );
    

    You have to use something like this:

    $jobsArray[$key] = $val;
    

    Otherwise, at each repeating loop, your syntax will override precedent array values.

    Then, I suggest you to use XPath to simplify entire process. With XPath queries, you can retrieve a set of nodes with only one search.

    Assuming you have this XML:

    <?xml version="1.0"?>
    <Jobs>
        <Job>
            <Client>
                <ID>8430219</ID>
                <Name>Fake Client</Name>
            </Client>
            <Client>
                <ID>8430220</ID>
                <Name>Fake Client 2</Name>
            </Client>
        </Job>
        <Job>
            <Client>
                <ID>8430221</ID>
                <Name>Fake Client 3</Name>
            </Client>
        </Job>
    </Jobs>
    

    With this xpath query:

    $clients = $oXML->xpath( '/Jobs/Job/Client' );
    

    you obtain in $clients all <Client> nodes. Then you can create your array in this way:

    $result = array();
    foreach( $clients as $client )
    {
        $result[$client->ID->__toString()] = $client->Name->__toString();
    }
    

    This is $result after foreach loop:

    Array
    (
        [8430219] => Fake Client
        [8430220] => Fake Client 2
        [8430221] => Fake Client 3
    )
    

    Note that we have to cast as string single nodes (that are SimpleXML objects): this is absolutely necessary creating keys, otherwise the array assignment fails. You can obtain same result using (string) $client->ID instead of $client->ID->__toString()