• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 139
  • Last Modified:

Trouble parsing soap xml result

Hi,
I can't seem to figure out the best way to parse the result of my curl/soap request.
For example, if all I was trying to do was get the BaseMSR value for below, how do I echo it out? Can't seem to access the value on its own. In a perfect world I'd convert it to json for the return

Code in my controller is:

$request = '
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>

<VehicleGet xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/PBS.PartnerHub.ServiceModel">
  <IncludeBuildVehicles>false</IncludeBuildVehicles>
  <IncludeInactive>false</IncludeInactive>
  <SerialNumber>9991.QA</SerialNumber>
  <VIN>WVGEF9BP1ED005013</VIN>
  <Year>2014</Year>
  <Year>VOLKSWAGEN</Year>
</VehicleGet>

</soap:Body>
</soap:Envelope>
';


$soapURL ="https://partnerhub.mydomain.com";
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $soapURL);
	$header[] = "Content-type: text/xml; charset=utf-8";
	$header[] = "SOAPAction: VehicleGet";
	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
	curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 60);
	
	$result = curl_exec($ch);
	
	curl_close($ch);
	
	dd($result);

Open in new window


Response below:
"<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<VehicleGetResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/PBS.PartnerHub.ServiceModel">
<Vehicles>
<Vehicle>
<Air>100.000000</Air>
<AppraisedValue>0.000000</AppraisedValue>
<BaseMSR>50975.000000</BaseMSR>
<Year>2014</Year>
</Vehicle>
</Vehicles>
</VehicleGetResponse>
</s:Body>
</s:Envelope>"

Open in new window

0
tjyoung
Asked:
tjyoung
  • 2
1 Solution
 
Ray PaseurCommented:
This is a bit of a hack, but it works.  SOAP is just awful, isn't it!
https://iconoun.com/demo/temp_tjyoung.php
<?php // demo/temp_tjyoung.php
/**
 * https://www.experts-exchange.com/questions/28979608/Trouble-parsing-soap-xml-result.html
 */
error_reporting(E_ALL);

$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<VehicleGetResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/PBS.PartnerHub.ServiceModel">
<Vehicles>
<Vehicle>
<Air>100.000000</Air>
<AppraisedValue>0.000000</AppraisedValue>
<BaseMSR>50975.000000</BaseMSR>
<Year>2014</Year>
</Vehicle>
</Vehicles>
</VehicleGetResponse>
</s:Body>
</s:Envelope>
EOD;

// MUNG THE XML AND MAKE AN OBJECT
$xml = mungXML($xml);
$obj = SimpleXML_Load_String($xml);

// EXTRACT THE DATA
$vehicle = $obj->s_Body->VehicleGetResponse->Vehicles->Vehicle;
$basemsr = $vehicle->BaseMSR;
var_dump($basemsr);

// FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE
function mungXML($xml)
{
    $obj = SimpleXML_Load_String($xml);
    if ($obj === FALSE) return $xml;

    // GET NAMESPACES, IF ANY
    $nss = $obj->getNamespaces(TRUE);
    if (empty($nss)) return $xml;

    // CHANGE ns: INTO ns_
    $nsm = array_keys($nss);
    foreach ($nsm as $key)
    {
        // A REGULAR EXPRESSION TO MUNG THE XML
        $rgx
        = '#'               // REGEX DELIMITER
        . '('               // GROUP PATTERN 1
        . '\<'              // LOCATE A LEFT WICKET
        . '/?'              // MAYBE FOLLOWED BY A SLASH
        . preg_quote($key)  // THE NAMESPACE
        . ')'               // END GROUP PATTERN
        . '('               // GROUP PATTERN 2
        . ':{1}'            // A COLON (EXACTLY ONE)
        . ')'               // END GROUP PATTERN
        . '#'               // REGEX DELIMITER
        ;
        // INSERT THE UNDERSCORE INTO THE TAG NAME
        $rep
        = '$1'          // BACKREFERENCE TO GROUP 1
        . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
        ;
        // PERFORM THE REPLACEMENT
        $xml =  preg_replace($rgx, $rep, $xml);
    }
    return $xml;
}

Open in new window

Outputs:
object(SimpleXMLElement)#4 (1) { [0]=> string(12) "50975.000000" }

Open in new window

0
 
tjyoungAuthor Commented:
Worked right out of the box and using a function is much cleaner in my case.
Thanks again. Always so concise.
0
 
Ray PaseurCommented:
Glad to help!  Thanks for the points and thanks for using E-E, ~Ray
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now