0

I am using simplexml_load_string in order to attempt to turn my XML file into variables I can later enter into a database however am struggling with the output working in some instances and not in others.

The xml

$response ='<ndxml version="2.0">
<status code="OK">
<response function="createNewJob" id="1">
    <status code="OK">
    <job uniqueref="5830z858279" jobref="858279">
        <consignment number="8613030">
        <reference>16755</reference>
        <deadlinedatetime date="2014-01-16" time="17:30:00">
        <jobnumber>
        <labeldata styletag="APC">
            <shippingdate date="15/01/2014">
            <addresses>
                <address type="COLLECTION">
                    <company>UK Stuff and Things</company>
                </address>
                <address type="DELIVERY">
                    <contact>Person</contact>
                    <telephone>02089636985</telephone>
                    <addresslines>
                        <addressline number="1">Daffy</addressline>
                        <addressline number="2">Things</addressline>
                        <addressline number="3">Places</addressline>
                        <addressline number="4">NORTHAMPTONSHIRE</addressline>
                    </addresslines>
                    <postzip>NB12 1ER</postzip>
                    <country isocode="GB">United Kingdom</country>
                </address>
            </addresses>
            <notes>
            <account code="21171">
            <tariff code="MP16">
            <routing>
                <delivery>
                    <route>LOCAL</route>
                    <zone>B</zone>
                    <driver>31</driver>
                    <serviceoptions>
                </serviceoptions></delivery>
                <depots>
                    <depot number="211" type="Sending">
                    <depot number="211" type="Request">
                    <depot number="211" type="Delivery">
                </depot></depot></depot></depots>
            </routing>
            <parcels total="1">
                <dimensions height="0" width="0" length="0">
                <volweight>0.0</volweight>
                <weight>0.14</weight>
                <parcel number="1">
                    <barcode>21163148613030001</barcode>
                </parcel>
            </dimensions></parcels>
        </tariff></account></notes></shippingdate></labeldata>
    </jobnumber></deadlinedatetime></consignment></job>
</status>
</response>

So I have managed to successfully grab certain elements from this by using the recommended code on the documentation:

$parsed=simplexml_load_string($response);
$response_statuscode = $parsed->status['code'];
$response_statuscode2 = $parsed->response->status['code'];
$response_consignment_num = $parsed->response->job->consignment['number'];
$response_reference = $parsed->response->job->reference;

All of these have worked exactly as required, however from there it all goes a bit wrong for me. Things with more complicated attributes (more than one!) just don't seem to be working for me.

 $response_date = $parsed->response->job->deadlinedatetime['date'];

I also tried:

 $parsed->response->job->deadlinedatetime->attributes()->date;

And from there on I can't seem to process anything from label data properly. I am just making a mess of my understanding of the tree?

 $response_account_code = $parsed->response->job->labeldata->account['code'];

As always, thanks in advance!

2
  • 1
    Personally I would run a print_r on the $parsed object, so that you can check that SimpleXML is actually walking over the XML as you expect. It will also tell you how to access, e.g -> or [] or foreach, or similar. Commented Jan 15, 2014 at 11:14
  • Aaron - you have hit the nail on the head - i tried the below solution but it wasn't playing friendly either. I then went back to my original solution and print_r'd it - whereas there were elements in the xml in lower case, in the print_r they had upper cases, therefore weren't being picked up correctly! Commented Jan 15, 2014 at 14:33

1 Answer 1

1

There's a very common approach to handle situations like this one:

Since simplexml_load_string() returns an object and since object property names cannot contain spaces, it would make sense to recursively convert an object into array.

You can use this function to do that:

function object2array($object) { 
   return json_decode(json_encode($object), true); 
}

$parsed = simplexml_load_string($response);

// Now, recursively convert it into an array
$parsed = object2array($parsed);

// Now you can access its values by keys, like this:
$parsed['response']['job']['labeldata']['account'];

As for dumping, you can simply do print_r($parsed)

Sign up to request clarification or add additional context in comments.

6 Comments

I feel like this is THE answer, but I'm a little confused. How do I process the values as per your last line. How would I get consignment from my example dump( [@attributes] => Array ( [version] => 2.0 ) [status] => Array ( [@attributes] => Array ( [code] => OK ) ) [response] => Array ( [@attributes] => Array ( [function] => createNewJob [id] => 1 ) [status] => Array ( [@attributes] => Array ( [code] => OK ) ) [job] => Array ( [@attributes] => Array ( [uniqueRef] => 5830z858343 [jobRef] => 858343 ) [consignment] => Array ( [@attributes] => Array ( [number] => 8613094 ) ) [reference] => 16756
If you add how you want an output would like, this will be much easer for me
So from this I'd like to have something like $uniqueref = (the output would be 5830z858343 in this case) $consignment_number = 8613094 in this case $reference = 16756 in this case Thanks for your help
Just noted that your response isn't actually valid XML, because there's no closing tag for first <status (look at the second and fourth lines, please). So I just removed <ndxml version="2.0"> and <status code="OK">, then got a consignment like this, $consignment = $parsed['status']['job']['consignment']['@attributes']['number']
Also, you could nicely output a result of $parsed by prepending <pre> tag. Try to dump it like : echo '<pre>' . print_r($parsed, 1) and surely this would make more sense
|

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.