I need to a value from this SOAP response. The value is in the loginresponse / return element. Here's the response:
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:body soap-env:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:DBCentralIntf-IDBCentral">
<ns1:loginresponse>
<return xsi:type="xsd:string"><**THIS IS THE VALUE I NEED**></return>
</ns1:loginresponse>
</soap-env:body>
Here's how I'm trying to parse:
$response = curl_exec($ch);
curl_close($ch);
$xml = simplexml_load_string($response, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$ns = $xml->getNamespaces(true);
$soap = $xml->children($ns['SOAP-ENV']);
$res = $soap->Body->children($ns['NS1']);
print_r($res->LoginResponse->Return);
But I get an empty object.
Thanks for your help!
Instead of using cURL and attempting to parse the XML response, consider using the PHP SOAP client. You may need to install PHP SOAP or enable it in your PHP configuration. (I'm using PHP on Windows, so I just had to uncomment extension=php_soap.dll in php.ini.)
If you have SOAP installed, you can get the WSDL from the provider of the web service you're using. Based on Googling this value in the XML you showed: xmlns:ns1="urn:DBCentralIntf-IDBCentral", I'm guessing you can find it here, but you'll probably have better luck finding it since you know for sure what web service you're using.
After you have the WSDL, using the PHP SOAP client is super easy:
$client = new SoapClient('path/to/your.wsdl');
$response = $client->Login(['username', 'password']);
$theValueYouNeed = $response->loginresponse->return;
UPDATE:
Removing the namespaces clears things up a bit (although a hack). Here my new code:
$response = curl_exec($ch);
curl_close($ch);
$cleanxml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $response);
$cleanxml = str_ireplace('NS1:','', $cleanxml);
$xml = simplexml_load_string($cleanxml);
echo $xml->Body->LoginResponse->return[0];
Related
I need send request for authenticate a SOAP via PHP SoapClient, but the request mount is result on "Not Found" after send.
On resume, using postman (plugin for chrome) i receive sucessful and the format XML mounted on a service is one and on another service is other. (each service mounted the XML different)
Via Postman i send this format (XML):
Work Correctly: I receive the correct response from server.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AutenticarUsuario xmlns="http://tempuri.org/PortalUAU_WS/Autenticador">
<Login>example</Login>
<Senha>123456</Senha>
</AutenticarUsuario>
</soap:Body>
</soap:Envelope>
Via SoapClient(PHP) he mount this format (XML):
Don't Work: I Receive "Not Found" no errors, no exceptions only "Not Found".
CODE PHP
public function authUauWeb(){
$soap = new \SoapClient($this->_wsEndpoint . 'Autenticador.asmx?WSDL', ['trace' => 1]);
$result = $soap->AutenticarUsuario(['Login' => $this->_wsData->user, 'Senha' => $this->_wsData->pass]);
//GET COOKIE SESSION
$headers = $soap->__getLastResponseHeaders();
$headers_init = strpos($headers, 'PortalUAU=');
if($headers_init !== false){
$headers = substr($headers, $headers_init);
$headers_end = strpos($headers, ';');
$headers = substr($headers, 0, $headers_end);
$headers = explode('=', $headers);
}
if(isset($result->AutenticarUsuarioResult) && $result->AutenticarUsuarioResult == 'True' && gettype($headers) == 'array'){
$this->_wsConnected = $headers;
}else{
$this->_wsConnected = false;
}
return $this->_wsConnected;
}
XML STRUCTURE FROM PHP
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/PortalUAU_WS/Autenticador" xmlns:ns2="http://200.178.248.110:90/PortalUAU_WS_HLG/Autenticador.asmx" xmlns:ns3="text/xml; charset=utf-8">
<SOAP-ENV:Header>
<ns2:SOAPAction/>
<ns3:ContentType/>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:AutenticarUsuario>
<ns1:Login>example</ns1:Login>
<ns1:Senha>123456</ns1:Senha>
</ns1:AutenticarUsuario>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
As we say here on Brazil "My kick" is about this soap vs SOAP-ENV and ns1: present on tags from xml.
Thanks!
I am getting Sabre SOAP API response something like :
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:header></soap-env:header>
<soap-env:body>
<ota_airlowfaresearchrs xmlns="http://www.opentravel.org/OTA/2003/05" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1.0" priceditincount="50" brandedonewayitincount="0" simpleonewayitincount="0" departeditincount="0" soldoutitincount="0" availableitincount="0">
<success>
<priceditineraries><priceditinerary sequencenumber="1"></priceditinerary>
<priceditinerary sequencenumber="2"></priceditinerary></priceditineraries>
</success>
</ota_airlowfaresearchrs>
</soap-env:body>
</soap-env:envelope>
But when I tried with simplexml_load_string I am getting a problem to convert it to PHP array. what I tried is :
$parser = simplexml_load_string($res);
$parserEnv = $parser->children('soap-env', true);
$response = $parserEnv->body->ota_airlowfaresearchrs;
its return emptry array like : SimpleXMLElement Object ( )
From
$parser = simplexml_load_string($res);
you have to change like below:
$parser = simplexml_load_string($res, "SimpleXMLElement", LIBXML_NOCDATA);
LIBXML_NOCDATA : You can use this function call to have simplexml convert CDATA into plain text.
As ref to : converting SOAP XML response to a PHP object or array
I got the answer by doing the following way:
$soap = simplexml_load_string($res);
$response = $soap->children('http://schemas.xmlsoap.org/soap/envelope/')
->body->children()
->ota_airlowfaresearchrs
->success
->priceditineraries
thanks #lalithkumar any way
I make a soap request and I get the following response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://*************/******/****" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://*************/******/****/***">
<SOAP-ENV:Body>
<ns1:GetEventV2Response>
<ns1:GetEventV2Result>
<ns1:Events>
<ns1:Event>
<ns1:Id>147624</ns1:Id>
<ns1:Name>Rockstars</ns1:Name>
<ns1:Genre>
...
I have tried to get the element ID inside of <ns1:Event>, but the code bellow doesn't work and don't know why. I searched and tried a fews solutions but without success.
header("Content-type: text/xml");
....
$response = curl_exec($ch);
curl_close($ch);
x = new SimpleXmlElement($response);
foreach($x->xpath('//ns1:Event') as $event) {
var_export($event->xpath('ns1:Id'));
}
why don't you try this?
$xml = simplexml_load_string($xml);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
foreach ($xml->xpath('//ns1:Event') as $item)
{
print_r($item);
}
http://php.net/manual/en/function.simplexml-load-string.php
Use SimpleXMLElement::registerXPathNamespace to register the namespace. For example:
$x->registerXPathNamespace('ns1', 'http://*************/******/****');
and, later:
$event->registerXPathNamespace('ns1', 'http://*************/******/****');
I'm trying to send user registrations with soap to another server. I'm creating an xml with DOMdocument and than after saveXML I'm running the soap which should return an xml with registration id plus all the data I sent in my xml.
But the Soap returns unknown error. exactly this: stdClass Object ( [RegisztracioInsResult] => stdClass Object ( [any] => 5Unknown error ) )
and this is how I send my xml.
/*xml creation with DOMdocument*/
$xml = saveXML();
$url = 'http://mx.biopont.com/services/Vision.asmx?wsdl';
$trace = '1';
$client = new SoapClient($url, array('trace' => $trace, "exceptions" => 0, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
$params = $client->RegisztracioIns(array('xml' => $xml));
$print_r($params);
If I click on the description of the RegisztracioIns service at this URL http://mx.biopont.com/services/Vision.asmx it shows me this:
POST /services/Vision.asmx HTTP/1.1
Host: mx.biopont.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://mx.biopont.com/services/RegisztracioIns"
<?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>
<RegisztracioIns xmlns="http://mx.biopont.com/services/">
<xml>string</xml>
</RegisztracioIns>
</soap:Body>
</soap:Envelope>
According to this I think I'm doing the upload correctly but maybe not I don't have much experience with soap.
Is there anything I'm missing? I also tried to save the xml to my server an than get the contents with file_get_contents(). but the result was the same.
You should be able to do something like this:
$res = $client->__soapCall( 'RegisztracioIns', array('xml'=>'my string to send'));
To have the wsdl wrap 'my string to send' in the proper tags.
You are doing something similar, but I dont think the wsdl is actually wrapping the string you are trying to pass, and passing nothing instead, resulting in unknown error.
You can examine the outgoing xml using $client->__getLastRequest();.
(Also, you have a small typo in your code on the last line should be print_r($params);.)
Failing that you could try to write the xml yourself using SoapVar() and setting the type to XSD_ANYXML.
It seems cleaner to me when the wsdl wraps everything for you, but its better than banging your head against the wall until it does.
I made an attempt to do just that with your wsdl. Give this a try:
$wsdl = "http://mx.biopont.com/services/Vision.asmx?wsdl";
$client = new SoapClient($wsdl, array( 'soap_version' => SOAP_1_1,
'trace' => true,
));
try {
$xml = "<RegisztracioIns xmlns='http://mx.biopont.com/services/'>
<xml>string</xml>
</RegisztracioIns>";
$args= array(new SoapVar($xml, XSD_ANYXML));
$res = $client->__soapCall( 'RegisztracioIns', $args );
var_dump($res);
} catch (SoapFault $e) {
echo "Error: {$e}";
}
print_r($client->__getLastRequest());
print_r($client->__getLastResponse());
I can't exactly read the response I am getting with that given that it is Hungarian (I think?). So let me know if that works for you.
To start off with, I am a beginner at soap.
I am trying to make a soap call to a service and was given a working sample that comes from talend. What I need is to make a similar call in PHP.
The output from talend is as follows, (extracted from the HTTP request)
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<root>
<request>
<username>a#a.com</username>
<password>md5sumlookalike</password>
<webservice>GetCust</webservice>
<refid>12343321</refid>
<message>reserv#123</message>
</request>
</root>
</soap:Body>
</soap:Envelope>
So I wrote a little bit of PHP as it works as a scripting language as well for where it will be called from. Trying to understand how to make a soap call I came up with this bit.
<?php
// Yes I know about the diffrent port issue here. So I wgeted and stored it for use next to script
# $soapClient = new SoapClient("http://123.123.123.123:8088/services", array("trace" => true));
$soapClient = new SoapClient("wsdl", array("trace" => true));
$error = 0;
try {
$info = $soapClient->__soapCall("invoke",
array
(
new SoapParam("a#a.com", "username"),
new SoapParam("md5sumish", "password"),
new SoapParam("GetCust", "webservice"),
new SoapParam("1234321", "refid"),
new SoapParam("reserv#123", "message")
)
);
} catch (SoapFault $fault) {
$error = 1;
echo 'ERROR: '.$fault->faultcode.'-'.$fault->faultstring;
}
if ($error == 0) {
print_r($output_headers);
echo 'maybe it worked\n';
unset($soapClient);
}
?>
I end up seeing the following in the HTTP request via wireshark. The server just does not know what to do with this and does not respond. I am unsure what/where I need to go from here.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://talend.org/esb/service/job">
<SOAP-ENV:Body>
<ns1:invokeInput>a#a.com</ns1:invokeInput>
<password>md5sumish</password>
<webservice>GetCust</webservice>
<refid>1234321</refid>
<message>reserv#123</message>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
So I have to ask is how to get rid of the ns1:invokeInput and make it username. Along with bring the rest of the format into line so the request looks like the output from talend?
Here is a working little script I did in php to call a talend tutorial service exported as soap:
//....
if (sizeof($_POST) > 0) {
$name = $_POST['name'];
$city = $_POST['city'];
$client = new SoapClient("http://192.168.32.205:8080/DirectoryService/services/DirectoryService?wsdl", array( 'trace' => 1));
$result = $client->runJob(array(
'--context_param',
'Name=' . $_POST['name'],
'--context_param',
'City=' . $_POST['city']
));
}
//...
Talend seems to be very "basic" regarding how parameters are given.
With this code it was working fine.