Parsing XML Response Objects [object(SimpleXMLElement)[x] from Walmart API Using CURL and SimpleXML

993 views Asked by At

Using the v3/orders part of the Walmart API to retrieve orders on a given day.

I am successfully receiving the response in an XML format.

<ns3:list xmlns:ns2="http://walmart.com/mp/orders" xmlns:ns3="http://walmart.com/mp/v3/orders" xmlns:ns4="http://walmart.com/">
  <ns3:meta>
     <ns3:totalCount>1</ns3:totalCount>
     <ns3:limit>10</ns3:limit>
  </ns3:meta>
<ns3:elements>
   <ns3:order>...</ns3:order>
</ns3:elements>

...
$result = curl_exec($ch);

Doing a var_dump($result); outputs the XML as a string.

enter image description here

Loading the string into a variable $xml = simplexml_load_string($result); and doing a var_dump($xml); outputs simply object(SimpleXMLElement)[2]

Trying to further narrow down the node path..

$list = $xml->{'ns3:list'};

outputs object(SimpleXMLElement)[3]

And trying to target ns3:elements with $elements = $xml->{'ns3:list'}->{'ns3:elements'};

var_dumps simply a null

I've verified that I am successfully receiving the a response of 200 using $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

I've also additionally tried encoding and decoding to an array and json using

$xml = simplexml_load_string($result, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

but still get an

array (size=0)
  empty

Why is the XML "stuck" in an object and how can I parse it's contents?

Very confused as to why I can't do anything with this string.

Here is the full script:

function pkcs8_to_pem($der) {

  static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----";
  static $END_MARKER = "-----END PRIVATE KEY-----";

  $value = base64_encode($der);

  $pem = $BEGIN_MARKER . "\n";
  $pem .= chunk_split($value, 64, "\n");
  $pem .= $END_MARKER . "\n";

  return $pem;
}

function getClientSignature($url, $request_type, $timestamp) {
  $walmart_secret = 'xxxxxxx';
  $walmart_consumer_id = 'xxxxxxxxx';

  $pem = pkcs8_to_pem(base64_decode($walmart_secret));
  $private_key = openssl_pkey_get_private($pem);

  $data = $walmart_consumer_id."\n";
  $data .= $url."\n";
  $data .= $request_type."\n";
  $data .= $timestamp."\n";

  $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
  if (!openssl_sign($data, $signature, $private_key, $hash)) {
    return null;
  }

  return base64_encode($signature);
}

$walmart_consumer_id = 'xxxxxxxxxxxx';
$walmart_channel_type = 'xxxxxxxxxxxxxxxxxxxx';

$request_type = "GET";

$yesterday2 = new DateTime();
$yesterday2->modify('-1 day');
$yesterday = $yesterday2->format('Y-m-d');

$url = "https://marketplace.walmartapis.com/v3/orders?createdStartDate=" . $yesterday;

$timestamp = round(microtime(true) * 1000);

$signature = getClientSignature($url, $request_type, $timestamp);

$headers = array();
$headers[] = "Accept: application/xml";
$headers[] = "WM_SVC.NAME: Walmart Marketplace";
$headers[] = "WM_CONSUMER.ID: ".$walmart_consumer_id;
$headers[] = "WM_SEC.TIMESTAMP: ".$timestamp;
$headers[] = "WM_SEC.AUTH_SIGNATURE: ".$signature;
$headers[] = "WM_QOS.CORRELATION_ID: ".mt_rand();
$headers[] = "WM_CONSUMER.CHANNEL.TYPE: " .$walmart_channel_type;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_type);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);

$xml = simplexml_load_string($result);

along with a sample xml output

<ns3:list xmlns:ns2="http://walmart.com/mp/orders" xmlns:ns3="http://walmart.com/mp/v3/orders" xmlns:ns4="http://walmart.com/">
   <ns3:meta>
      <ns3:totalCount>1</ns3:totalCount>
       <ns3:limit>10</ns3:limit>
   </ns3:meta>
  <ns3:elements>
  <ns3:order>
    <ns3:purchaseOrderId>2575693098967</ns3:purchaseOrderId>
    <ns3:customerOrderId>4021603941547</ns3:customerOrderId>
    <ns3:customerEmailId>[email protected]</ns3:customerEmailId>
    <ns3:orderDate>2016-05-11T23:16:10.000Z</ns3:orderDate>
    <ns3:shippingInfo>
        <ns3:phone>6502248603</ns3:phone>
        <ns3:estimatedDeliveryDate>2016-05-20T17:00:00.000Z</ns3:estimatedDeliveryDate>
        <ns3:estimatedShipDate>2016-05-16T17:00:00.000Z</ns3:estimatedShipDate>
        <ns3:methodCode>Standard</ns3:methodCode>
        <ns3:postalAddress>
            <ns3:name>Madhukara PGOMS</ns3:name>
            <ns3:address1>860 W Cal Ave</ns3:address1>
            <ns3:address2>Seat # 860C.2.176</ns3:address2>
            <ns3:city>Sunnyvale</ns3:city>
            <ns3:state>CA</ns3:state>
            <ns3:postalCode>94086</ns3:postalCode>
            <ns3:country>USA</ns3:country>
            <ns3:addressType>RESIDENTIAL</ns3:addressType>
        </ns3:postalAddress>
    </ns3:shippingInfo>
    <ns3:orderLines>
        <ns3:orderLine>
            <ns3:lineNumber>1</ns3:lineNumber>
            <ns3:item>
                <ns3:productName>Garmin Refurbished nuvi 2595LMT 5 GPS w Lifetime Maps and Traffic</ns3:productName>
                <ns3:sku>GRMN100201</ns3:sku>
            </ns3:item>
            <ns3:charges>
                <ns3:charge>
                    <ns3:chargeType>PRODUCT</ns3:chargeType>
                    <ns3:chargeName>ItemPrice</ns3:chargeName>
                    <ns3:chargeAmount>
                        <ns3:currency>USD</ns3:currency>
                        <ns3:amount>124.98</ns3:amount>
                    </ns3:chargeAmount>
                    <ns3:tax>
                        <ns3:taxName>Tax1</ns3:taxName>
                        <ns3:taxAmount>
                            <ns3:currency>USD</ns3:currency>
                            <ns3:amount>10.94</ns3:amount>
                        </ns3:taxAmount>
                    </ns3:tax>
                </ns3:charge>
            </ns3:charges>
            <ns3:orderLineQuantity>
                <ns3:unitOfMeasurement>EACH</ns3:unitOfMeasurement>
                <ns3:amount>1</ns3:amount>
            </ns3:orderLineQuantity>
            <ns3:statusDate>2016-05-11T23:43:50.000Z</ns3:statusDate>
            <ns3:orderLineStatuses>
                <ns3:orderLineStatus>
                    <ns3:status>Created</ns3:status>
                    <ns3:statusQuantity>
                        <ns3:unitOfMeasurement>EACH</ns3:unitOfMeasurement>
                        <ns3:amount>1</ns3:amount>
                    </ns3:statusQuantity>
                </ns3:orderLineStatus>
            </ns3:orderLineStatuses>
        </ns3:orderLine>
    </ns3:orderLines>
  </ns3:order>
 </ns3:elements>
</ns3:list>

What's the proper way to parse any of the individual nodes in this scenario?

1

There are 1 answers

2
OsDev On BEST ANSWER

you can simply traverse de XML using the namespace declaration

<?php

$xml = 'YOUR_XML_STRING';

$data = simplexml_load_string($xml,'SimpleXMLElement',0,'http://walmart.com/mp/v3/orders');

echo (string) $data->meta->totalCount; 

//you have to cast the value to get the text value of an element also you can traverse items like this

foreach($data->elements as $el){ $el->order->purchaseOrderId }