I'm getting an simplexml object from:
$xml = simplexml_load_string($data);
If I do dd($xml) I get the following string in console:
SimpleXMLElement {#232
+"Data": SimpleXMLElement {#240}
+"Error": SimpleXMLElement {#241}
+"xmlData": "<root><row><FiscalCode>27221245</FiscalCode><CompanyName>Nume Companie SRL</CompanyName><LegalForm>SRL</LegalForm><RegistrationNumber>J40/111/2010</RegistrationNumber><DateOfIncorporation>2010-07-29</DateOfIncorporation><Status>functiune;</Status><ShareCapital>1.510000000000000e+005</ShareCapital><NACE>6201</NACE><NACE_Descr>Activităţi de realizare a soft-ului la comandă (software orientat client)</NACE_Descr><PrimaryActivityVersion>2</PrimaryActivityVersion><NumberOfemployees>20</NumberOfemployees><County>Municipiul Bucuresti</County><City>BUCURESTI SECTORUL 5</City><Street>DR. JOSEPH LISTER</Street><Number>22</Number><Block /><Entrance /><Floor /><Apartment>1</Apartment><PostalCode>50543</PostalCode><PhoneNumber>0724063943</PhoneNumber><E-mail /><Web /><OwnershipForm /><CompanyIdentification>certificat de înmatriculare preschimbat; </CompanyIdentification><UpdateOn>2018-07-04</UpdateOn><Headquarters_DocumentType>Contract de închiriere</Headquarters_DocumentType><Headquarters_DocumentDuringType>Temporar</Headquarters_DocumentDuringType><Headquarters_DocumentNumber>1</Headquarters_DocumentNumber><Headquarters_DocumentDate>01-11-2016</Headquarters_DocumentDate><HeadquartersExpiryDayFrom>2016-11-01</HeadquartersExpiryDayFrom><HeadquartersExpiryDayUntil>2019-11-01</HeadquartersExpiryDayUntil><DateofIncorporationDocument>2018-07-03</DateofIncorporationDocument><SecondaryHeadquarters><row><Name>Punct de lucru</Name><StartDate /><StopDate /><Country>ROMANIA</Country><Locality>BUCUREŞTI SECTORUL 5</Locality><Street>DR. STAICOVICI</Street><Number>19</Number><Block /><Entrance /><Floor>1</Floor><Apartment>2</Apartment><District>5</District><PostalCode /></row><row><Name>PUNCT DE LUCRU</Name><StartDate>2013-05-01 00:00:00.0000000</StartDate><StopDate>2014-05-01 00:00:00.0000000</StopDate><Country>ROMANIA</Country><Locality>BUCUREŞTI SECTORUL 5</Locality><Street>B-dul EROILOR</Street><Number>13</Number><Block /><Entrance /><Floor /><Apartment>2</Apartment><District>5</District><PostalCode /></row></SecondaryHeadquarters></row></root>"
}
Which the correct way to extract FiscalCode
I mention that
dd($xml->FiscalCode) return nothing.
also
dd($xml->root->row->FiscalCode); does not work
The original xml is get from an external link:
It looks like that:
<?xml version="1.0" encoding="utf-8"?>
<Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Data>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded" />
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" />
</Data>
<Error />
<xmlData><root><row><FiscalCode>27225145</FiscalCode><CompanyName>Nume Companie SRL</CompanyName><LegalForm>SRL</LegalForm><RegistrationNumber>J40/7213/2010</RegistrationNumber><DateOfIncorporation>2010-07-29</DateOfIncorporation><Status>functiune;</Status><ShareCapital>1.510000000000000e+005</ShareCapital><NACE>6201</NACE><NACE_Descr>Activităţi de realizare a soft-ului la comandă (software orientat client)</NACE_Descr><PrimaryActivityVersion>2</PrimaryActivityVersion><NumberOfemployees>20</NumberOfemployees><County>Municipiul Bucuresti</County><City>BUCURESTI SECTORUL 5</City><Street>DR. JOSEPH LISTER</Street><Number>22</Number><Block /><Entrance /><Floor /><Apartment>1</Apartment><PostalCode>50543</PostalCode><PhoneNumber>0724063943</PhoneNumber><E-mail /><Web /><OwnershipForm /><CompanyIdentification>certificat de înmatriculare preschimbat; </CompanyIdentification><UpdateOn>2018-07-04</UpdateOn><Headquarters_DocumentType>Contract de închiriere</Headquarters_DocumentType><Headquarters_DocumentDuringType>Temporar</Headquarters_DocumentDuringType><Headquarters_DocumentNumber>1</Headquarters_DocumentNumber><Headquarters_DocumentDate>01-11-2016</Headquarters_DocumentDate><HeadquartersExpiryDayFrom>2016-11-01</HeadquartersExpiryDayFrom><HeadquartersExpiryDayUntil>2019-11-01</HeadquartersExpiryDayUntil><DateofIncorporationDocument>2018-07-03</DateofIncorporationDocument><SecondaryHeadquarters><row><Name>Punct de lucru</Name><StartDate /><StopDate /><Country>ROMANIA</Country><Locality>BUCUREŞTI SECTORUL 5</Locality><Street>DR. STAICOVICI</Street><Number>19</Number><Block /><Entrance /><Floor>1</Floor><Apartment>2</Apartment><District>5</District><PostalCode /></row><row><Name>PUNCT DE LUCRU</Name><StartDate>2013-05-01 00:00:00.0000000</StartDate><StopDate>2014-05-01 00:00:00.0000000</StopDate><Country>ROMANIA</Country><Locality>BUCUREŞTI SECTORUL 5</Locality><Street>B-dul EROILOR</Street><Number>13</Number><Block /><Entrance /><Floor /><Apartment>2</Apartment><District>5</District><PostalCode /></row></SecondaryHeadquarters></row></root></xmlData>
</Result>
I get the link like that:
$curl = curl_init();
curl_setopt_array($curl, Array(
CURLOPT_URL => 'https://wsprokolekt.rocomp.ro/service.asmx/CompanyGeneralInformation?idUser=*****&CUI=******',
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_ENCODING => 'UTF-8'
));
$data = curl_exec($curl);
$xml = simplexml_load_string($data);
Thank you for you time!
First, read and decode xmlData and then get FiscalCode
$xml = simplexml_load_string($str);
$xml1 = simplexml_load_string(html_entity_decode($xml->xmlData));
echo $xml1->row->FiscalCode;
Related
I tried the solutions of How to parse this SOAP XML response with PHP simplexml_load_string?, but it doesn't work.
Maybe someone have an idea to how to parse this Soap XML result, you find the soap.xml and result and the test
Soap.xml
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ...>
<wsdl:documentation>soapExemple</wsdl:documentation>
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://.../xsd">
...
Output:
<?php
ini_set("soap.wsdl_cache_enabled", "0");
const USER = "userHere";
const PASSWORD = "passHere";
$credentials = array('login' => USER, 'password' => PASSWORD);
$options = array("trace" => 1, "exception" => 0, 'encoding' => 'UTF-8');
$url = "pass/to/wsdl.xml";
$soap = new SoapClient($url, $credentials);
var_dump($soap);
try {
$result = $soap->__soapCall("reclis_XML", array("parameters"=>array("args0"=>array("METHODHERE" => "01"))));
var_dump($result);
} catch (SoapFault $exception) {
\Zend_Debug::dump( 'Exception Thrown: '.$exception->faultstring);
}
?>
Result:
object(stdClass)#6591 (1) {
["return"] => string(39171) "<?xml version="1.0" encoding="UTF-8"?>
<RECLIS>
<RESULT>KO</RESULT>
<REAL>0</REAL>
<RUS>
<REAL>0</REAL>
<CUSTOMER>
<CLEMAJ></CLEMAJ>
<NAME></NAME>
<LASTNALE>0</LASTNALE>
<PHONE>0</PHONE>
<AD></AD>
<ADDRESS1></ADDRESS1>
<ADDRESS2></ADDRESS2>
<CITY></CITY>
<CODE></CODE>
<PRICE>0</PRICE>
</CUSTOMER>
<CUSTOMER>
<CLEMAJ></CLEMAJ>
<NAME></NAME>
<LASTNALE>0</LASTNALE>
<PHONE>0</PHONE>
<AD></AD>
<ADDRESS1></ADDRESS1>
<ADDRESS2></ADDRESS2>
<CITY></CITY>
<CODE></CODE>
<PRICE>0</PRICE>
</CUSTOMER>
<CUSTOMER>
<CLEMAJ></CLEMAJ>
<NAME></NAME>
<LASTNALE>0</LASTNALE>
<PHONE>0</PHONE>
<AD></AD>
<ADDRESS1></ADDRESS1>
<ADDRESS2></ADDRESS2>
<CITY></CITY>
<CODE></CODE>
<PRICE>0</PRICE>
</CUSTOMER>
...
</RUS>
</RECLIS>
"
}
I tried this but it doesn't work:
$xml=simplexml_load_string($myXMLData) or die("Error: Cannot create object");
print_r($xml);
Have you an idea or another solution to get my xml result as an array
You have to get the string by accessing the return property
Try using:
$xml=simplexml_load_string($myXMLData->return) or die("Error: Cannot create object");
print_r($xml);
I HAVE THIS XML RESPONSE FROM A SOAP CALL:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><loginResponse xmlns="http://wws.adomain.com/"><loginResult><xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"><xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="replay" msdata:UseCurrentLocale="true"><xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"><xs:element name="replay"><xs:complexType><xs:sequence><xs:element name="code" type="xs:string" minOccurs="0" /><xs:element name="description" type="xs:string" minOccurs="0" /></xs:sequence></xs:complexType></xs:element></xs:choice></xs:complexType></xs:element></xs:schema><diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"><DocumentElement xmlns=""><replay diffgr:id="replay1" msdata:rowOrder="0" diffgr:hasChanges="inserted"><code>OK</code><description>
<?xml version="1.0" encoding="UTF-8"?><root><token>e6d354f2-b284569e20-b2def8f3ef4a</token><nmDealer>SAP001 NAME</nmDealer><idRegDealer>8763</idRegDealer><idRegGrupo>-1</idRegGrupo><idRegPuntoVenta>-1</idRegPuntoVenta><idRegUsuario>35350731</idRegUsuario><idRegVendedor>-1</idRegVendedor><idRegZona>-1</idRegZona><dsTpUsuario>CLIENTES</dsTpUsuario><dsPais>PRODUCCION</dsPais><idioma>EN</idioma><idRegIdioma>9</idRegIdioma><isImputar>False</isImputar><moneda>€</moneda><tpUsuario>1</tpUsuario><idRegComisionVariableDealer>-1</idRegComisionVariableDealer><permitirComisionVariableDealer>1</permitirComisionVariableDealer><firstAccess>0</firstAccess><acceptedConditions>False</acceptedConditions><idRegInsured>-1</idRegInsured><idRegAuditor>-1</idRegAuditor></root></description></replay></DocumentElement></diffgr:diffgram></loginResult></loginResponse></soap:Body></soap:Envelope>
http://prntscr.com/9cfdwk
I want to be able to get the values of element (eg token) in the second xml tag (<?xml version="1.0" encoding="UTF-8"?>) Any prompt assistance will be appreciated.
HERE IS MY CODE:
$s = new soapclientw($wsdlfile);
if (empty($proxyhost))
{
}
else{
$s->setHTTPProxy($proxyhost,$proxyport,$proxyusr,$proxypassword);
}
$result = $s->send($msg,'http://wws.domain.com/login',60);
$myXMLData = $s->responseData;
libxml_use_internal_errors(true);
$xml = simplexml_load_string($myXMLData);
if ($xml === false) {
echo "Failed loading XML: ";
foreach(libxml_get_errors() as $error) {
echo "<br>", $error->message;
}
}
else{
echo $xml->token;
}
Given your original, highly dubious xml, the following is a bit of a hack but it works..
$strxml='
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<loginResponse xmlns="http://wws.adomain.com/">
<loginResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="replay" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="replay">
<xs:complexType>
<xs:sequence>
<xs:element name="code" type="xs:string" minOccurs="0" />
<xs:element name="description" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<DocumentElement xmlns="">
<replay diffgr:id="replay1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<code>OK</code>
<description>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<token>e6d354f2-b284569e20-b2def8f3ef4a</token>
<nmDealer>SAP001 NAME</nmDealer>
<idRegDealer>8763</idRegDealer>
<idRegGrupo>-1</idRegGrupo>
<idRegPuntoVenta>-1</idRegPuntoVenta>
<idRegUsuario>35350731</idRegUsuario>
<idRegVendedor>-1</idRegVendedor>
<idRegZona>-1</idRegZona>
<dsTpUsuario>CLIENTES</dsTpUsuario>
<dsPais>PRODUCCION</dsPais>
<idioma>EN</idioma>
<idRegIdioma>9</idRegIdioma>
<isImputar>False</isImputar>
<moneda>€</moneda>
<tpUsuario>1</tpUsuario>
<idRegComisionVariableDealer>-1</idRegComisionVariableDealer>
<permitirComisionVariableDealer>1</permitirComisionVariableDealer>
<firstAccess>0</firstAccess>
<acceptedConditions>False</acceptedConditions>
<idRegInsured>-1</idRegInsured>
<idRegAuditor>-1</idRegAuditor>
</root>
</description>
</replay>
</DocumentElement>
</diffgr:diffgram>
</loginResult>
</loginResponse>
</soap:Body>
</soap:Envelope>';
$strxml=htmlentities( $strxml );
$search=array(
htmlentities( '<?xml version="1.0" encoding="utf-8"?>' ),
htmlentities( '<?xml version="1.0" encoding="UTF-8"?>' )
);
$strxml=html_entity_decode( str_replace( $search, '', $strxml ) );
libxml_use_internal_errors( true );
$dom = new DOMDocument('1.0','utf-8');
$dom->validateOnParse=false;
$dom->standalone=true;
$dom->preserveWhiteSpace=true;
$dom->strictErrorChecking=false;
$dom->substituteEntities=false;
$dom->recover=true;
$dom->formatOutput=false;
$dom->loadXML( $strxml );
libxml_clear_errors();
$col=$dom->getElementsByTagName('root')->item(0);
if( $col ){
foreach( $col->childNodes as $node ) echo $node->tagName.' '.$node->nodeValue.BR;
}
$dom=null;
Thanks all, I was able to figure it out myself.
Here is the code that worked for me:
$myXMLData = strip_tags($s->responseData);
$temp = explode("OK", $myXMLData);
$myXMLData = $temp[1];
$xml = new SimpleXMLElement(htmlspecialchars_decode($myXMLData));
I stripped off all the soap tags, living me with the final xml data but with a leading 'OK' which I removed by explode(). Replacing the 'OK' with an empty string would have also worked.
I am getting below error after requesting SOAP call.
fault code: HTTP, fault string: Bad Request
Is this badly formed message?
try{
$client = new SoapClient("http://ip_add/something.asmx?WSDL", array("trace" => true, 'exceptions' => 1));
$params = new \SoapVar('<?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>
<RemittanceService xmlns="http://tempuri.org/">
<CreditTxnMessage xmlns="http://my_url">
<Corporate_UID xmlns="">66666</Corporate_UID>
<Mandate_Type xmlns="">P</Mandate_Type>
<MICR_No xsi:nil="true" xmlns="" />
<Instrument_No xsi:nil="true" xmlns="" />
<Remitter_Address1 xmlns="">285 enfiled pl</Remitter_Address1>
<Remitter_Address2 xmlns="">mississauga</Remitter_Address2>
<Remitter_Address3 xmlns="">16y2n4</Remitter_Address3>
<Remitter_Country xmlns="">Canada</Remitter_Country>
<Remitter_ZIP_Code xsi:nil="true" xmlns="" />
<Remitter_EmailID xsi:nil="true" xmlns="" />
<Remitter_Contact_No xmlns="" />
<Beneficiary_ZIP_Code xsi:nil="true" xmlns="" />
<Beneficiary_EmailID xsi:nil="true" xmlns="" />
<Beneficiary_Contact_No xmlns="" />
<Beneficiary_Bank_Name xmlns="">PNB</Beneficiary_Bank_Name>
</CreditTxnMessage>
</RemittanceService>
</soap:Body>
</soap:Envelope>', XSD_ANYXML);
$result = $client->__soapCall('RemittanceService', array($params));
highlight_string($client->__getLastRequest());
}
catch(SoapFault $fault){
die("SOAP Fault:<br />fault code: {$fault->faultcode}, fault string: {$fault->faultstring}");
}
I don't know what's wrong here.
Stack Trace
SoapFault exception: [HTTP] Bad Request in /var/www/mtes/public_html/application/controllers/bank_api_pnb.php:146
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://124.124....', 'http://tempuri....', 1, 0)
#1 /var/www/mtes/public_html/application/controllers/bank_api_pnb.php(146): SoapClient->__soapCall('RemittanceServi...', Array)
#2 [internal function]: Bank_api_pnb->test()
#3 /var/www/mtes/public_html/system/core/CodeIgniter.php(359): call_user_func_array(Array, Array)
#4 /var/www/mtes/public_html/index.php(220): require_once('/var/www/mtes/p...')
#5 {main}
The whole point of the SoapClient is to convert calls to xml; so you shouldn't be doing this manually. Try this instead:
try {
$client = new SoapClient("http://ip_add/something.asmx?WSDL", array("trace" => true, 'exceptions' => 1));
$result = $client->RemittanceService(array(
'CreditTxnMessage' => array(
'Corporate_UID' => 66666,
'Mandate_Type' => 'P',
'MICR_No' => null,
/* you get the idea */
'Beneficiary_Contact_No' => '',
'Beneficiary_Bank_Name' => 'PNB'
)
));
highlight_string($client->__getLastRequest());
}
catch(SoapFault $fault){
die("SOAP Fault:<br />fault code: {$fault->faultcode}, fault string: {$fault->faultstring}");
}
The exact format of the parameters and their names would be specified in the WSDL.
Generally a Bad Request response to a SOAP request is returned when the message is not in a good format (invalid header, body, ..) and therefor the document can't be parsed. First of all try to remove the XML version declaration from your SoapVar and see if it fixes the problem (remove the line below):
<?xml version="1.0" encoding="UTF-8"?>
Alternatively you can always test your Soap requests in tools like SoapUI to make sure they work and then complete your code. If it doesn't work in SoapUI it means there is something wrong with the request. Try to revise the WS and make sure you are sending everything in the correct format (eg. maybe you need to authenticate? SoapHeader? ..)
I am not to familiar with PHP but try this.
$Request = '<RemittanceService xmlns="http://tempuri.org/">
<CreditTxnMessage xmlns="http://my_url">
<Corporate_UID xmlns="">66666</Corporate_UID>
<Mandate_Type xmlns="">P</Mandate_Type>
<MICR_No xsi:nil="true" xmlns="" />
<Instrument_No xsi:nil="true" xmlns="" />
<Remitter_Address1 xmlns="">285 enfiled pl</Remitter_Address1>
<Remitter_Address2 xmlns="">mississauga</Remitter_Address2>
<Remitter_Address3 xmlns="">16y2n4</Remitter_Address3>
<Remitter_Country xmlns="">Canada</Remitter_Country>
<Remitter_ZIP_Code xsi:nil="true" xmlns="" />
<Remitter_EmailID xsi:nil="true" xmlns="" />
<Remitter_Contact_No xmlns="" />
<Beneficiary_ZIP_Code xsi:nil="true" xmlns="" />
<Beneficiary_EmailID xsi:nil="true" xmlns="" />
<Beneficiary_Contact_No xmlns="" />
<Beneficiary_Bank_Name xmlns="">PNB</Beneficiary_Bank_Name>
</CreditTxnMessage>
</RemittanceService>';
$result = $client->__doRequest($Request, "http://ip_add/something.asmx", "RemittanceService", soap_1_2, 0);
I'm not sure how SoapVar works, but I would advise against passing in raw XML to the SoapClient. I would try to recreate the XML structure in PHP arrays (painful, I know), especially since the XML appears in the stack trace:
$params = array(
"RemittanceService" => array("xmlns"=>"http://tempuri.org/", "_" => array(
"CreditTxnMessage" => array("xmlns" => "http://my_url", "_" => array(
"Corporate_UID" => array("xmlns" => "", "_" => 66666),
"Mandate_Type" => array("xmlns" => "", "_" => "P"),
"MICR_No" => array("xsi:nil" => "true", "xmlns" => ""),
// and so on...
))
))
);
Also, you should probably specify the SOAP version (SOAP_1_1 or SOAP_1_2) in the constructor of the SOAPClient:
$client = new SoapClient("http://ip_add/something.asmx?WSDL", array('soap_version' => SOAP_1_2, "trace" => true, 'exceptions' => 1));
Also, the arguments array in __soapCall() is pretty picky about the formatting. Try the following:
$result = $client->__soapCall('RemittanceService', array('parameters' => $params));
Or even:
$result = $client->__soapCall('RemittanceService', $params);
I'm basically guessing as to what the issue is, so this isn't a very thorough solution. You can also try looking elsewhere on SO. For example, this answer uses SoapVar.
I am building a service against Sonos' Music API (SMAPI). Sometimes I have to send back a response in the following format:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>Client.NOT_LINKED_RETRY</faultcode>
<faultstring>Link Code not found retry...</faultstring>
<detail>
<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
<SonosError>5</SonosError>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I am building my service using the PHP SOAP library and for the above response I tried throwing a SoapFault like this:
throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...');
But when I try this the response that is sent back looks like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>Client.NOT_LINKED_RETRY</faultcode>
<faultstring>Link Code not found retry...</faultstring>
<detail>
<SonosError/>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Notice that there is no ExceptionInfo and that SonosError is empty. Is it possible to set ExceptionInfo and SonosError using SoapFault? I tried all kinds of things, but couldn't get it working, so as a work around I am doing this now:
http_response_code(500);
header("Content-type: text/xml");
$ret = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$ret .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
$ret .= '<SOAP-ENV:Body>';
$ret .= '<SOAP-ENV:Fault>';
$ret .= '<faultcode>Client.NOT_LINKED_RETRY</faultcode>';
$ret .= '<faultstring>Link Code not found retry...</faultstring>';
$ret .= '<detail>';
$ret .= '<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>';
$ret .= '<SonosError>5</SonosError>';
$ret .= '</detail>';
$ret .= '</SOAP-ENV:Fault>';
$ret .= '</SOAP-ENV:Body>';
$ret .= '</SOAP-ENV:Envelope>'."\n";
echo $ret; exit;
Not sure if it's relevant but the WSDL can be found here.
Update: when I try the suggestion below like this:
$detail = new StdClass();
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';
throw new SoapFault(
'Client.NOT_LINKED_RETRY',
'Link Code not found retry...',
NULL,
$detail
);
I get:
<detail>
<customFault>
<SonosError>5</SonosError>
<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
</customFault>
</detail>
This is almost what I need, except for <customFault> tag. Is there a way to get rid of it and have SonosError and ExceptionInfo in <detail> directly?
The fact that you don't see the ExceptionInfo tag is because it is not defined in the wsdl. On the other hand SonosError is defined.
First thing first, in order to fill the SonosError you have to pass the arguments.
From here you can see that the constructor has more parameters
SoapFault('code', 'string', 'actor', 'detail', 'name', 'header');
In order to pass the SonosError call it like this
$detail = new StdClass();
$detail->SonosError = 5;
throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...', null, $details);
As for the ExceptionInfo, the wsdl must be changed. As it is now, the details tag is represented by this sections
<wsdl:message name="customFault">
<wsdl:part name="customFault" element="tns:SonosError"/>
</wsdl:message>
<xs:element name="SonosError" type="xs:int"/>
If you change the above sections with these, you will have what you need.
<wsdl:message name="customFault">
<wsdl:part name="customFault" type="tns:customFaultType" />
</wsdl:message>
<xs:complexType name="customFaultType">
<xs:sequence>
<xs:element name="SonosError" type="xs:int"/>
<xs:element name="ExceptionInfo" type="xs:string"/>
</xs:sequence>
</xs:complexType>
And of course you add the parameter and the array becomes like this
$detail = new StdClass();
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';
I'm attempting to get data from a Web Service using PHP/SOAP and the response dataset is always empty. I believe that the issue lays in how I set the dsParams parameter.
This is the Web Service URL
If I use SoapUI and send this request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:max="http://www.maxhire.net/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soapenv:Header>
<max:AuthHeader>
<!--Optional:-->
<max:DatabaseName>Name</max:DatabaseName>
<!--Optional:-->
<max:SecurityKey>Key</max:SecurityKey>
</max:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<max:ExecuteCustomStoredProcedureGetResults>
<max:strProcName>JobPostings</max:strProcName>
<max:dsParams>
<xs:schema id="NewDataSet" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Table">
<xs:complexType>
<xs:sequence>
<xs:element name="ParamName" type="xs:string" minOccurs="0"/>
<xs:element name="ParamValue" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
</max:dsParams>
</max:ExecuteCustomStoredProcedureGetResults>
</soapenv:Body>
</soapenv:Envelope>
I get a desired result.
Each web method that is called using SOAP must pass appropriate security credentials. These credentials must be specified in the SOAP header as DatabaseName and SecurityKey. This part is working correctly.
According to the documentation:
About dsParams
A few things to note about the dsParams dataset that you must pass to use either of these functions (e.g. ExecuteCustomStoredProcedureGetResults):
Even if you have no parameters, you must pass a dataset object that contains one initialized tabled.
If you do have parameters, you must have two columns in that table that are named “ParamName” and “ParamValue”.
Each parameter should be its own row in the table with its name in the first column and value in the second.
Note: I do not have parameters.
Below is an example of one of many ways I’ve attempted to approach this task. It is the closest that I can get without getting errors.
$client = new SoapClient('https://www.maxhire.net/MaxHireAPI/UserServices.asmx?wsdl',array('trace' => TRUE));
$header = new SoapHeader(
'http://www.maxhire.net/',
'AuthHeader',array(
'DatabaseName' => 'Name',
'SecurityKey' => 'Key'
),
false
);
$client->__setSoapHeaders($header);
try {
$jobs = new stdClass();
$jobs->strProcName = 'JobPostings';
$jobs->NewDataSet = new stdClass();
$jobs->NewDataSet->Table = new stdClass();
$jobs->NewDataSet->Table->ParamName = '';
$jobs->NewDataSet->Table->ParamValue = '';
$result = $client->ExecuteCustomStoredProcedureGetResults($jobs);
echo "<pre>\n";
var_dump($result);
echo "</pre>\n";
}
catch(SoapFault $soapfault){
echo "<pre>\n";
var_dump($soapfault);
echo "</pre>\n";
}
The following is the response that I get:
object(stdClass)#7 (1) {
["ExecuteCustomStoredProcedureGetResultsResult"]=>
object(stdClass)#8 (2) {
["schema"]=>
string(323) "<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet"><xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"><xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"/></xs:complexType></xs:element></xs:schema>"
["any"]=>
string(127) "<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"/>"
}
}
echo "Request:\n" . $client->__getLastRequest() . "<br />\n";
Request:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.maxhire.net/">
<SOAP-ENV:Header>
<ns1:AuthHeader>
<ns1:DatabaseName>Name</ns1:DatabaseName>
<ns1:SecurityKey>Key</ns1:SecurityKey>
</ns1:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ExecuteCustomStoredProcedureGetResults>
<ns1:strProcName>JobPostings</ns1:strProcName>
</ns1:ExecuteCustomStoredProcedureGetResults>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
echo "Response:\n" . $client->__getLastResponse() . "<br />\n";
Response:
<?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>
<ExecuteCustomStoredProcedureGetResultsResponse xmlns="http://www.maxhire.net/">
<ExecuteCustomStoredProcedureGetResultsResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded" />
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" />
</ExecuteCustomStoredProcedureGetResultsResult>
</ExecuteCustomStoredProcedureGetResultsResponse>
</soap:Body>
</soap:Envelope>