Welcome to WebmasterWorld Guest from 54.166.112.74

Forum Moderators: coopster & jatar k

Message Too Old, No Replies

Parsing SOAP response

Unable to parse SOAP response

   
4:10 am on Mar 31, 2008 (gmt 0)

5+ Year Member



I am trying to retrieve "RateReply->RatedShipmentDetails->ShipmentRateDetail->TotalNetCharge->Amount" from the following response but all my attempts have been fruitless.
Any help will be greatly appreciated.
Thank you in advance.

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<soapenv:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v3:RateReply xmlns:v3="http://example.com/ws/rate/v3">
<v3:HighestSeverity>SUCCESS</v3:HighestSeverity>
<v3:Notifications>
<v3:Severity>SUCCESS</v3:Severity>
<v3:Source>crs</v3:Source>
<v3:Code>0</v3:Code>
<v3:Message>Request was successfully processed</v3:Message>
<v3:LocalizedMessage>Request was successfully processed</v3:LocalizedMessage>
</v3:Notifications>
<ns1:TransactionDetail xmlns:ns1="http://example.com/ws/rate/v3" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<ns1:CustomerTransactionId>sid_t9oib6rv5d0n5fm004vinr34t7_d_2008-03-30_z_75243</ns1:CustomerTransactionId>
</ns1:TransactionDetail>
<ns1:Version xmlns:ns1="http://example.com/ws/rate/v3" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<ns1:ServiceId>crs</ns1:ServiceId>
<ns1:Major>3</ns1:Major>
<ns1:Intermediate>0</ns1:Intermediate>
<ns1:Minor>0</ns1:Minor>
</ns1:Version>
<v3:IneligibleForMoneyBackGuarantee>false</v3:IneligibleForMoneyBackGuarantee>
<v3:OriginServiceArea>A2</v3:OriginServiceArea>
<v3:DestinationServiceArea>A2</v3:DestinationServiceArea>
<v3:TransitTime>TWO_DAYS</v3:TransitTime>
<v3:SignatureOption>SERVICE_DEFAULT</v3:SignatureOption>
<v3:ActualRateType>PAYOR_ACCOUNT</v3:ActualRateType>
<v3:RatedShipmentDetails>
<v3:ShipmentRateDetail>
<v3:RateType>PAYOR_ACCOUNT</v3:RateType>
<v3:RateZone>5</v3:RateZone>
<v3:DimDivisor>0</v3:DimDivisor>
<v3:FuelSurchargePercent>6.0</v3:FuelSurchargePercent>
<v3:TotalBillingWeight>
<v3:Units>LB</v3:Units>
<v3:Value>29.0</v3:Value>
</v3:TotalBillingWeight>
<v3:TotalBaseCharge>
<v3:Currency>USD</v3:Currency>
<v3:Amount>12.8</v3:Amount>
</v3:TotalBaseCharge>
<v3:TotalFreightDiscounts>
<v3:Currency>USD</v3:Currency>
<v3:Amount>0.0</v3:Amount>
</v3:TotalFreightDiscounts>
<v3:TotalNetFreight>
<v3:Currency>USD</v3:Currency>
<v3:Amount>12.8</v3:Amount>
</v3:TotalNetFreight>
<v3:TotalSurcharges>
<v3:Currency>USD</v3:Currency>
<v3:Amount>7.27</v3:Amount>
</v3:TotalSurcharges>
<v3:TotalTaxes>
<v3:Currency>USD</v3:Currency>
<v3:Amount>0.0</v3:Amount>
</v3:TotalTaxes>
<v3:TotalNetCharge>
<v3:Currency>USD</v3:Currency>
<v3:Amount>20.07</v3:Amount>
</v3:TotalNetCharge>
<v3:TotalRebates>
<v3:Currency>USD</v3:Currency>
<v3:Amount>0.0</v3:Amount>
</v3:TotalRebates>
</v3:ShipmentRateDetail>
</v3:RatedShipmentDetails>
</v3:RateReply>
</soapenv:Body>
</soapenv:Envelope>
9:10 am on Mar 31, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



Welcome to WebmasterWorld, aim2678!
Have a look at the XML parser [php.net] functions.
If you're on php5, you could probably also do it with Simple XML [php.net].
5:18 am on Apr 1, 2008 (gmt 0)

5+ Year Member



Thank you for the quick response Cameraman.

I tried using the SimpleXML but I encountered the following error message;

Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: Entity: line 1: parser error : Start tag expected, '<' not found in /home/content/a/u/g/test/html/example/ratelookup.php on line 158
Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: HTTP/1.1 200 OK in /home/content/a/u/g/test/html/example/RatePackage.php on line 158
Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: ^ in /home/content/a/u/g/test/html/example/RatePackage.php on line 158
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /home/content/a/u/g/test/html/example/RatePackage.php:158 Stack trace: #0 /home/content/a/u/g/test/html/example/RatePackage.php(158): SimpleXMLElement->__construct('HTTP/1.1 200 OK...') #1 /home/content/a/u/g/test/html/library/functions.php(175): include('/home/content/a...') #2 /home/content/a/u/g/test/html/cart.php(24): shippingTaxCalculator('75069') #3 {main} thrown in /home/content/a/u/g/test/html/example/RatePackage.php on line 158

I believe it is occuring because I have to get a substring of the response to get to the XML due to the fact that "HTTP/1.1 200 OK Server: Sun-ONE-Web-Server/6.1 Date: Tue, 01 Apr 2008 03:24:22 GMT Content-length: 2546 Content-type: text/xml; charset=utf-8 X-Powered-By: Servlet/2.4 JSP/2.0 " appears before the first XML tag is encountered within the response.

However I noticed that getting a substring appears to have it's own set pf problems because the first '<' is evaluted as '&lt;'.

Do you know how I can access the XML for this string so that I can parse through it properly?

Thank you!

6:31 am on Apr 1, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



That's odd - what are you using to get the substring?
I suppose you could try html_entity_decode [us.php.net] to convert them back.
2:47 am on Apr 2, 2008 (gmt 0)

5+ Year Member



For some reason that did not work however I figured out how to remove the "HTTP/1.1 200 OK Server: Sun-ONE-Web-Server/6.1 Date: Tue, 01 Apr 2008 03:24:22 GMT Content-length: 2546 Content-type: text/xml; charset=utf-8 X-Powered-By: Servlet/2.4 JSP/2.0 " from the header of the response (by setting CURLOPT_HEADER to false).

Even though I have eliminated the need to run a substring, I am still unable to parse the response to retrieve the shipping rate (below is a snapshot of my code for your reference).

FYI - I was initially running the request via SOAP however my hosting account doesn't allow me to run the request directly so I have run it through a proxy. I tried to specify a proxy via SOAP however my request would always fail so I decided to use cURL (which might be a bad idea since my response is not in XML).

Do you know what might be causing the issue?
Thank you!

$FedExRateRequest = <<< XMLREQUEST
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v3">
<SOAP-ENV:Body>
<ns1:RateRequest>
<ns1:WebAuthenticationDetail>
<ns1:UserCredential>
<ns1:Key>123456</ns1:Key>
<ns1:Password>987654</ns1:Password>
</ns1:UserCredential>
</ns1:WebAuthenticationDetail>
<ns1:ClientDetail>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:MeterNumber>111111</ns1:MeterNumber>
</ns1:ClientDetail>
<ns1:TransactionDetail>
<ns1:CustomerTransactionId>123345433</ns1:CustomerTransactionId>
</ns1:TransactionDetail>
<ns1:Version>
<ns1:ServiceId>crs</ns1:ServiceId>
<ns1:Major>3</ns1:Major>
<ns1:Intermediate>0</ns1:Intermediate>
<ns1:Minor>0</ns1:Minor>
</ns1:Version>
<ns1:Origin>
<ns1:StreetLines>100 Test Street</ns1:StreetLines>
<ns1:City>Cincinatti</ns1:City>
<ns1:StateOrProvinceCode>OH</ns1:StateOrProvinceCode>
<ns1:PostalCode>45241</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Origin>
<ns1:Destination>
<ns1:StreetLines/>
<ns1:City/>
<ns1:StateOrProvinceCode/>
<ns1:PostalCode>75243</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Destination>
<ns1:Payment>
<ns1:PaymentType>SENDER</ns1:PaymentType>
</ns1:Payment>
<ns1:DropoffType>REGULAR_PICKUP</ns1:DropoffType>
<ns1:ServiceType>$shippingServiceType</ns1:ServiceType>
<ns1:PackagingType>YOUR_PACKAGING</ns1:PackagingType>
<ns1:ShipDate>$currentDate</ns1:ShipDate>
<ns1:RateRequestTypes>ACCOUNT</ns1:RateRequestTypes>
<ns1:PackageCount>1</ns1:PackageCount>
<ns1:Packages>
<ns1:InsuredValue>
<ns1:Currency>USD</ns1:Currency>
<ns1:Amount>0</ns1:Amount>
</ns1:InsuredValue>
<ns1:Weight>
<ns1:Units>LB</ns1:Units>
<ns1:Value>40</ns1:Value>
</ns1:Weight>
<ns1:Dimensions>
<ns1:Length>0</ns1:Length>
<ns1:Width>0</ns1:Width>
<ns1:Height>0</ns1:Height>
<ns1:Units>IN</ns1:Units>
</ns1:Dimensions>
<ns1:SpecialServicesRequested>
<ns1:SpecialServiceTypes>NON_STANDARD_CONTAINER</ns1:SpecialServiceTypes>
</ns1:SpecialServicesRequested>
</ns1:Packages>
</ns1:RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XMLREQUEST;

$submiturl = "https://example.test.com:443/web-services";
$user_agent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $submiturl);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt ($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
curl_setopt ($ch, CURLOPT_PROXY,"http://proxy.xyz.secureserver.net:3128");
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $FedExRateRequest);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
curl_setopt($ch, CURLOPT_POST, 1);

$FedExRateResponse = curl_exec($ch);

if (curl_error($ch))
{
$EmailErrorSubject = 'Concession Palace - FedEx Exception Error';
$EmailErrorMessage = "Errors were encountered: " . curl_errno($ch) . curl_error($ch);
$EmailErrorMessage += ' - occurred at ' . date('c');
mail('webmaster@example.com',$EmailErrorSubject,$EmailErrorMessage,'From: webmaster@example.com');
curl_close($ch);
$_SESSION['ShippingZipCode'] = "";
header('Location: error.php');
}
else
{
curl_close($ch);

$FedExRateResponseXML = htmlentities($FedExRateResponse);

$_SESSION['ShippingCost'] = $FedExRateResponseXML->{'v3:RateReply'}->{'v3:RatedShipmentDetails'}->{'v3:ShipmentRateDetail'}->{'v3:TotalNetCharge'}->{'v3:Amount'};
}

print_r($FedExRateResponseXML);

[edited by: eelixduppy at 4:14 am (utc) on April 2, 2008]
[edit reason] exemplified [/edit]

7:11 am on Apr 2, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



Just to make absolutely sure, you're doing this:
$FedExRateResponseXML = htmlentities($FedExRateResponse);

just for display purposes, right? You're not doing that to the response that you're trying to process?

1:13 pm on Apr 2, 2008 (gmt 0)

5+ Year Member



I am running

$FedExRateResponseXML = htmlentities($FedExRateResponse);

so that I can parse the converted response (i.e. $FedExRateResponseXML) to retrieve the shipping rate.
If I don't then the response is not in XML.
Am I approaching this the wrong way?
Thank you!

3:55 pm on Apr 2, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



htmlentities [us.php.net] - Convert all applicable characters to HTML entities

It turns characters like < and > into &lt; and &gt;

Now that you've got the header stuff stripped off try your script without it.

5:29 pm on Apr 2, 2008 (gmt 0)

5+ Year Member



I tried processing the response without "$FedExRateResponseXML = htmlentities($FedExRateResponse);" and it failed.
Below is a snapshot of what the response looks like;

SUCCESSSUCCESScrs0Request was successfully processedRequest was successfully processed sid_6e3cq4q2n29de3ckrua84j29g7_d_2008-04-02_z_75243 crs 3 0 0 falseA2A2TWO_DAYSSERVICE_DEFAULTPAYOR_ACCOUNTPAYOR_ACCOUNT506.0LB20.0USD9.51USD0.0USD9.51USD7.07USD0.0USD16.58USD0.0

I am not sure how I can convert it into a format that I can easily parse through (unless there is a way I can parse it without formating the string). Any suggestions will be greatly appreciated.
Thank you!

10:00 pm on Apr 2, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



Ok I just saved your request to a file and tried it and got all kinds of whining about the namespace. So I stripped that and it seems to be much happier:
$xmltxt = join('',file('ww_ratetest.xml'));
$xmltxt = preg_replace('#(</?)ns1:#','$1',$xmltxt);
$xml = new SimpleXMLElement($xmltxt);
echo "<p>" . $xml->RateRequest->TransactionDetail->CustomerTransactionId . "</p>\n";

You could probably define the namespace in the response, but to me it's easier to just yank it out. Change the 'ns1:' in the regular expression to the namespace in the response (looks from your post that it's v3:) and see how that goes.

1:20 pm on Apr 4, 2008 (gmt 0)

5+ Year Member



The solution you provided would have worked in my case if the response was in XML. Below is a snapshot of what the response looks like;

SUCCESSSUCCESScrs0Request was successfully processedRequest was successfully processed sid_6e3cq4q2n29de3ckrua84j29g7_d_2008-04-02_z_75243 crs 3 0 0 falseA2A2TWO_DAYSSERVICE_DEFAULTPAYOR_ACCOUNTPAYOR_ACCOUNT506.0LB20.0USD9.51USD0.0USD9.51USD7.07USD0.0USD16.58USD0.0

I have tried several things to try and get it to work (without any success).

Is there an parameter in cURL that I can specify to return a response in XML?
Thank you!

4:23 pm on Apr 4, 2008 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



You could maybe try CURLOPT_BINARYTRANSFER although I don't think that should be necessary - are you sure it's not coming back as xml (have you viewed source)? Have you tried saving the return in a file and then looking at the file?
9:12 pm on Apr 4, 2008 (gmt 0)

5+ Year Member



Hi, I am having this same probelm. The problem that I am facing is how to parse, the XML response, that, I am getting. Any help will be appreciated.
9:40 pm on Apr 4, 2008 (gmt 0)

5+ Year Member



Ok, buddy. I have found the answer. Just do this,

echo($response->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount);

And you will get the result.

10:14 pm on Apr 4, 2008 (gmt 0)

5+ Year Member



Ok, buddy, here's a more generic version. It will work no matter what response has come.

foreach ($response -> RatedShipmentDetails as $RatedShipmentDetails)
{
if(is_array($response -> RatedShipmentDetails))
{
echo $RatedShipmentDetails -> ShipmentRateDetail->TotalNetCharge->Currency;
echo ': ';
echo $RatedShipmentDetails -> ShipmentRateDetail->TotalNetCharge->Amount . $newline;
}
else
{
echo $RatedShipmentDetails . $newline;
}
}

11:37 pm on Apr 4, 2008 (gmt 0)

5+ Year Member



rupakbanerjee - Are you also running the request via cURL? If so, could you please show me how you are running the request and parsing the response.
Thank you!
7:05 am on Apr 5, 2008 (gmt 0)

5+ Year Member



I am using SOAP to run the request, the same, for fedex rates. It will not matter as how the request is made, via curl or anything else. The result will be the same.
4:49 pm on Apr 5, 2008 (gmt 0)

5+ Year Member



I do not run into any issues retrieving the response when I run it via SOAP however I cannot use it because my hosting account requires me to run the request through a proxy (hence why I have to use cURL).
Are you running your request via a proxy? If so, could you provide a sample so I can see how you are running it?
Thank you!
8:40 pm on Apr 5, 2008 (gmt 0)

5+ Year Member



I managed to get this issue resolved by running the request via SOAP.

I found out that the "proxy_port" parameter must be an integer not a string (i.e. 123 works however "123" fails).

I would like to thank you both for assisting me to resolve this issue.

Thanks again!

8:51 pm on Apr 5, 2008 (gmt 0)

5+ Year Member



Hi,

Now, I need some help. This is my XML schema.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v3">
<SOAP-ENV:Body><ns1:RateRequest>
<ns1:WebAuthenticationDetail>
<ns1:UserCredential>
<ns1:Key>yeFlflsOfHknbEGC</ns1:Key>
<ns1:Password>9Nng0sY4l6Jg9wkdeKnKAv3YT</ns1:Password>
</ns1:UserCredential>
</ns1:WebAuthenticationDetail>
<ns1:ClientDetail>
<ns1:AccountNumber>510087860</ns1:AccountNumber>
<ns1:MeterNumber>1229519</ns1:MeterNumber>
</ns1:ClientDetail>
<ns1:TransactionDetail>
<ns1:CustomerTransactionId>5682345</ns1:CustomerTransactionId>
</ns1:TransactionDetail>
<ns1:Version>
<ns1:ServiceId>crs</ns1:ServiceId>
<ns1:Major>3</ns1:Major>
<ns1:Intermediate>0</ns1:Intermediate>
<ns1:Minor>0</ns1:Minor>
</ns1:Version>
<ns1:Origin>
<ns1:StreetLines>Sender Address Line 1</ns1:StreetLines>
<ns1:PostalCode>149063</ns1:PostalCode>
<ns1:CountryCode>SG</ns1:CountryCode>
</ns1:Origin>
<ns1:Destination>
<ns1:StreetLines>Destination Address Line 1</ns1:StreetLines>
<ns1:PostalCode>700050</ns1:PostalCode>
<ns1:CountryCode>IN</ns1:CountryCode>
</ns1:Destination>
<ns1:Payment>
<ns1:PaymentType>SENDER</ns1:PaymentType>
</ns1:Payment>
<ns1:DropoffType>REGULAR_PICKUP</ns1:DropoffType>
<ns1:ServiceType>INTERNATIONAL_PRIORITY</ns1:ServiceType>
<ns1:PackagingType>YOUR_PACKAGING</ns1:PackagingType>
<ns1:ShipDate>2008-04-05</ns1:ShipDate>
<ns1:RateRequestTypes>LIST</ns1:RateRequestTypes>
<ns1:RateRequestPackageSummary>
<ns1:PieceCount>2</ns1:PieceCount>
<ns1:TotalWeight><ns1:Units>LB</ns1:Units>
<ns1:Value>20</ns1:Value>
</ns1:TotalWeight>
<ns1:TotalInsuredValue>
<ns1:Currency>USD</ns1:Currency>
<ns1:Amount>100</ns1:Amount>
</ns1:TotalInsuredValue>
<ns1:SpecialServicesRequested>
<ns1:SpecialServiceTypes>NON_STANDARD_CONTAINER</ns1:SpecialServiceTypes>
</ns1:SpecialServicesRequested>
</ns1:RateRequestPackageSummary>
</ns1:RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I am getting this ::

Error in processing transaction.

FAILURE
crs
999
Internal or unexpected error
Internal or unexpected error

Any help will be appreciated.

11:11 pm on Apr 5, 2008 (gmt 0)

5+ Year Member



Interesting. Have you made any changes recently?
Are you running the request in Dev or Production?
I have encountered similar errors before in Dev and it is usually a FedEx issue. To confirm, you can contact their Technical Support department.
I hope this helps.