-1

This might be quite usual for some of you but I'm not familiar with XML Data Parsing using PHP as you might be!

Situation

My client's company (e-Commerce) has a tie-up with a Logistics Company which has its own API for tracking shipments/packages. Now my client wants to automate the Tracking for all packages they ship for their orders using API Integration with the credentials provided by the Logistics Company.

We have been provided the link to access the Live API, which responds data in XML format. I have already worked out with XML Responses/Data of the following type -

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<ShipmentData>
<Shipment>
<Origin>New Delhi (110001)</Origin>
<Status>
<Status>Pending</Status>
<StatusLocation>Ahmedabad(Gujarat)</StatusLocation>
<StatusDateTime>2017-06-13T09:53:28.063000</StatusDateTime>
<RecievedBy/>
<Instructions>Reattempt - As per NDR instructions</Instructions>
<StatusType>UD</StatusType>
</Status>
</Shipment>
</ShipmentData>

For my convenience & understanding I have tagged the above Result as named XML Fields, as every row is named individually

But the result which is receive from this new Logistics Company is different as it has attributes like name, type which are a part of every row.

XML Response as below -

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<bd-objects version="1.0">
<object pk="1" model="awb">
<field type="BigIntegerField" name="awb_number">120420921</field>
<field type="CharField" name="orderid">123456</field>
<field type="FloatField" name="actual_weight">0.5</field>
<field type="CharField" name="origin">DELHI - DLU</field>
<field type="CharField" name="destination">BANGALORE - BAN</field>
<field type="CharField" name="current_location_name">DELHI - DEP</field>
<field type="CharField" name="current_location_code">DEP</field>
<field type="CharField" name="customer">ABC TRADING COMPANY</field>
<field type="CharField" name="consignee">John Doe</field>
<field type="CharField" name="pickupdate">13-Jun-2017</field>
<field type="CharField" name="status">Bagging completed</field>
<field type="CharField" name="tracking_status">Connected</field>
<field type="CharField" name="reason_code"/>
<field type="CharField" name="reason_code_description"/>
<field type="CharField" name="reason_code_number">001</field>
<field type="CharField" name="receiver"/>
<field type="CharField" name="expected_date">20-Jun-2017</field>
<field type="CharField" name="last_update_date">18-Jun-2017</field>
<field type="CharField" name="delivery_date"/>
<field type="CharField" name="ref_awb">None</field>
<field type="CharField" name="rts_shipment">0</field>
<field type="CharField" name="system_delivery_update"/>
<field type="CharField" name="rts_system_delivery_status"/>
<field type="CharField" name="rts_reason_code_number"/>
<field type="CharField" name="rts_last_update"/>
<field type="CharField" name="pincode">560001</field>
<field type="CharField" name="city">BANGALORE</field>
<field type="CharField" name="state">Karnataka</field>
<field name="scans">...</field>
</object>
</bd-objects>

Now I want each of the following named fields like awb_number,orderid,origin,consignee to be stored in different variable like $awb_number , $orderid, $origin , $consignee so that I can make use of it for my further processing code which updates the status of the shipment on request from the server.

For the named field XML response I used the following code -

$url= "https://track.bd.com/api/packages/xml/?token=xxxxxxxxxxxxxxxx&format=xml&output=xml&waybill="."$awb";
$dh = curl_init();
curl_setopt($dh, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($dh, CURLOPT_URL, $url);  //Get the URL Contents

$data = curl_exec ($dh); // Execute Curl Request


$xml = simplexml_load_string($data);


foreach ($xml -> Shipment as $row) {

$status_type = $row ->  StatusType;
$PickUpDate = $row -> PickUpDate;
$Destination = $row -> Destination;
$PickDate = date("Y-m-d H:i:s",strtotime($PickUpDate));
$PickedDate = date("d M Y",strtotime($PickUpDate));
$ReferenceNo = $row -> ReferenceNo;
$DispatchCount = $row -> DispatchCount;
$OrderType = $row -> OrderType;

}

foreach ($xml -> Shipment->Status as $row) {

$status = $row -> Status;
$status_type = $row ->  StatusType;

$Instructions = $row -> Instructions;
$status_time = $row -> StatusDateTime;
$statustime = date("j M Y",strtotime($status_time));
}
foreach ($xml -> Shipment->Consignee as $row) {

$Name = $row -> Name;
$PinCode = $row ->  PinCode;
$Telephone1 = $row -> Telephone1;
$Address1 = $row -> Address1;
$ReverseInTransit = $row -> ReverseInTransit;
$ReturnedDate = $row -> ReturnedDate;
}
curl_close($dh);

The above code worked like a charm as the fields are named but in the second result set I'm unable to figure out as to what code should be used to store result values from XML to PHP Variables.

Alpha
  • 321
  • 6
  • 16

1 Answers1

0

DOMDocument to the rescue!

<?php
declare(strict_types=1);
$domd=@DOMDocument::loadHTML(getXML()); // PS,. if its strict xml, you should probably replace loadHTML with loadXML
foreach($domd->getElementsByTagName("object")->item(0)->getElementsByTagName("field") as $field){
    $name=$field->getAttribute("name");
    $type=$field->getAttribute("type");
    $text=$field->textContent;
    echo 'name: '.$name.PHP_EOL;
    echo 'type: '.$type.PHP_EOL;
    echo 'text: '.$text.PHP_EOL;
}    
function getXML():string{
    $xml=<<<'XML'
<bd-objects version="1.0">
<object pk="1" model="awb">
<field type="BigIntegerField" name="awb_number">120420921</field>
<field type="CharField" name="orderid">123456</field>
<field type="FloatField" name="actual_weight">0.5</field>
<field type="CharField" name="origin">DELHI - DLU</field>
<field type="CharField" name="destination">BANGALORE - BAN</field>
<field type="CharField" name="current_location_name">DELHI - DEP</field>
<field type="CharField" name="current_location_code">DEP</field>
<field type="CharField" name="customer">ABC TRADING COMPANY</field>
<field type="CharField" name="consignee">John Doe</field>
<field type="CharField" name="pickupdate">13-Jun-2017</field>
<field type="CharField" name="status">Bagging completed</field>
<field type="CharField" name="tracking_status">Connected</field>
<field type="CharField" name="reason_code"/>
<field type="CharField" name="reason_code_description"/>
<field type="CharField" name="reason_code_number">001</field>
<field type="CharField" name="receiver"/>
<field type="CharField" name="expected_date">20-Jun-2017</field>
<field type="CharField" name="last_update_date">18-Jun-2017</field>
<field type="CharField" name="delivery_date"/>
<field type="CharField" name="ref_awb">None</field>
<field type="CharField" name="rts_shipment">0</field>
<field type="CharField" name="system_delivery_update"/>
<field type="CharField" name="rts_system_delivery_status"/>
<field type="CharField" name="rts_reason_code_number"/>
<field type="CharField" name="rts_last_update"/>
<field type="CharField" name="pincode">560001</field>
<field type="CharField" name="city">BANGALORE</field>
<field type="CharField" name="state">Karnataka</field>
<field name="scans">...</field>
</object>
</bd-objects>
XML;
return $xml;
}

output:

name: awb_number
type: BigIntegerField
text: 120420921
name: orderid
type: CharField
text: 123456
name: actual_weight
type: FloatField
text: 0.5
name: origin
type: CharField
text: DELHI - DLU
name: destination
type: CharField
text: BANGALORE - BAN
name: current_location_name
type: CharField
text: DELHI - DEP
name: current_location_code
type: CharField
text: DEP
name: customer
type: CharField
text: ABC TRADING COMPANY
name: consignee
type: CharField
text: John Doe
name: pickupdate
type: CharField
text: 13-Jun-2017
name: status
type: CharField
text: Bagging completed
name: tracking_status
type: CharField
text: Connected
name: reason_code
type: CharField
text: 
name: reason_code_description
type: CharField
text: 
name: reason_code_number
type: CharField
text: 001
name: receiver
type: CharField
text: 
name: expected_date
type: CharField
text: 20-Jun-2017
name: last_update_date
type: CharField
text: 18-Jun-2017
name: delivery_date
type: CharField
text: 
name: ref_awb
type: CharField
text: None
name: rts_shipment
type: CharField
text: 0
name: system_delivery_update
type: CharField
text: 
name: rts_system_delivery_status
type: CharField
text: 
name: rts_reason_code_number
type: CharField
text: 
name: rts_last_update
type: CharField
text: 
name: pincode
type: CharField
text: 560001
name: city
type: CharField
text: BANGALORE
name: state
type: CharField
text: Karnataka
name: scans
type: 
text: ...
hanshenrik
  • 19,904
  • 4
  • 43
  • 89