使用 CURL 和简单 XML 从沃尔玛 API 解析 XML 响应对象 [object(SimpleXMLElement)[x]
Parsing XML Response Objects [object(SimpleXMLElement)[x] from Walmart API Using CURL and SimpleXML
使用沃尔玛 API 的 v3/orders
部分检索指定日期的订单。
我已成功收到 XML 格式的回复。
<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);
执行 var_dump($result);
输出 XML 作为字符串。
将字符串加载到变量 $xml = simplexml_load_string($result);
并执行 var_dump($xml);
输出只是 object(SimpleXMLElement)[2]
正在尝试进一步缩小节点路径..
$list = $xml->{'ns3:list'};
输出object(SimpleXMLElement)[3]
并尝试用 $elements = $xml->{'ns3:list'}->{'ns3:elements'};
定位 ns3:elements
var_dumps只是一个null
我已经确认我使用 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
成功收到了 200
的回复
我还尝试使用
对数组进行编码和解码,json
$xml = simplexml_load_string($result, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
但仍然得到
array (size=0)
empty
为什么 XML "stuck" 在 object
中,我该如何解析它的内容?
很困惑为什么我不能用这个字符串做任何事情。
这是完整的脚本:
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);
连同示例 xml 输出
<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>mgr@walmartlabs.com</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>
在这种情况下解析任何单个节点的正确方法是什么?
您可以使用命名空间声明
简单地遍历 de XML
<?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 }
使用沃尔玛 API 的 v3/orders
部分检索指定日期的订单。
我已成功收到 XML 格式的回复。
<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);
执行 var_dump($result);
输出 XML 作为字符串。
将字符串加载到变量 $xml = simplexml_load_string($result);
并执行 var_dump($xml);
输出只是 object(SimpleXMLElement)[2]
正在尝试进一步缩小节点路径..
$list = $xml->{'ns3:list'};
输出object(SimpleXMLElement)[3]
并尝试用 $elements = $xml->{'ns3:list'}->{'ns3:elements'};
ns3:elements
var_dumps只是一个null
我已经确认我使用 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
200
的回复
我还尝试使用
对数组进行编码和解码,json$xml = simplexml_load_string($result, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
但仍然得到
array (size=0)
empty
为什么 XML "stuck" 在 object
中,我该如何解析它的内容?
很困惑为什么我不能用这个字符串做任何事情。
这是完整的脚本:
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);
连同示例 xml 输出
<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>mgr@walmartlabs.com</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>
在这种情况下解析任何单个节点的正确方法是什么?
您可以使用命名空间声明
简单地遍历 de XML<?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 }