916 Networks
916 Networks

Reputation: 545

Working with results from CURL call XML

I have been working with some code for many hours today, wondering if someone could point me in a better direction than I'm going now.

I have PHP code that is fetching an array of data by sending XML via send_request_via_curl($host,$path,$content).

My function:

function send_request_via_curl($host,$path,$content)
{
$posturl = "https://" . $host . $path;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $posturl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: application/x-www-form-urlencoded"));
    curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml;charset=utf-8"));
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    return $response;
}

$headers = array(
    "Content-type: text/xml;charset=utf-8",
    "Accept: application/xml",
    "Cache-Control: no-cache",
    "Pragma: no-cache",
    "Content-length: " . strlen($content),
    );


$content = '<?xml version="1.0" encoding="utf-8"?>
                <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>
                <GetLocations xmlns="http://tempuri.org/">
                    <AuthLogin>ClientName</AuthLogin>
                    <UserName>MyUser</UserName>
                    <Password>SomePassword</Password>
                </GetLocations>
            </soap:Body>
            </soap:Envelope>';

$response = send_request_via_curl($host,$path,$content);

EDIT:

I'm getting closer, I implemented Baba's code and now getting a different error:

Warning: Unknown: Node no longer exists in....

I have the same code from above, with this now processing the response:

if ($response)
{

$xml = new SimpleXMLElement($response);
$xml->registerXPathNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$path = $xml->xpath("//soap:Body");
$path = $path[0] ;
foreach($path->GetLocationsResponse->GetLocationsResult->SearchLocations->children() as $table)
{
echo $table->Table->LocationName . "<br>";
}

Here's the true XML returned - I noticed Firebug made all the XML lowercase, whereas the source code has capitals mixed in which I think might matter.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetLocationsResponse xmlns="http://tempuri.org/">
<GetLocationsResult>
<SearchLocations>
<Table>
<LocationName>
</Table>
<Table>
<LocationId>103501</LocationId>
<LocationName>Albuquerque, New Mexico, USA</LocationName>
</Table>
<Table>
<LocationId>101600</LocationId>
<LocationName>Atlanta, Georgia, USA</LocationName>
</Table>
</SearchLocations>
</GetLocationsResponse>
</GetLocationsResult>
</soap:Body>
</soap:Envelope>

THANKS!!!

Upvotes: 1

Views: 1751

Answers (2)

Baba
Baba

Reputation: 95161

The response you got is not HTML but XML but it looks like Your XML is wrong there is an invalid tag or you must have made mistake ... see

  <LocationName>Hawaii</Location>
                             ^--- it should be LocationName

It should be like this

<?xml version="1.0" encoding="utf-8"?>
<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>
        <getlocationsresponse xmlns="http://tempuri.org">
            <getlocationsresult>
                <SearchLocations>
                    <Table>
                        <LocationID>10322</LocationID>
                        <LocationName>Hawaii</LocationName>
                    </Table>
                </SearchLocations>
            </getlocationsresult>
        </getlocationsresponse>
    </soap:Body>
</soap:Envelope>

Read This XML

$xml = new SimpleXMLElement($data);
$xml->registerXPathNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$path = $xml->xpath("//soap:Body");
$path = $path[0] ;
foreach($path->getlocationsresponse->getlocationsresult->SearchLocations->children() as $table)
{
     echo $table->LocationName . "<br>";
}

Output

 Hawaii

------ Edit --------

Your new XML is wrong again .. this is what it should look like http://codepad.org/JgJfqnrA

Upvotes: 3

Adam
Adam

Reputation: 1090

Baba is correct, the built in functions for parsing XML are the best way to do this but you could also use regex if the XML is really sent back with mismatching tags.

function regex_all( $capture, $haystack, $return=1 ) {
  preg_match_all( "#$capture#", $haystack, $match );
  return $match[ $return ];
}

foreach( regex_all('<LocationName>(.*?)<\/', $data) as $locationName ) {
  echo "$locationName<br>";
}

This would not be the preferred method because the regex isn't as reliable.

Upvotes: 1

Related Questions