0

I do a Soap request but I obtain an string imposible to convert to XML, what is the problem?

This is what I do:

$url = "https://test.com/services";

            $XML ='<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>
                    <Consult Localitation xmlns="Services/">
                    <XMLin>
                    &lt;ConsultXMLin Language=&quot;1&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;
                    &lt;Consult&gt;
                    &lt;Code&gt;XXXXX0700005020128012D&lt;/Code&gt;
                    &lt;/Consult&gt;
                    &lt;/ConsultXMLin&gt;</XMLin>
                    </Consult Localitation></soap:Body>
                    </soap:Envelope>';

                   $ch = curl_init();

                   curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
                   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
                   curl_setopt($ch, CURLOPT_HEADER, FALSE);
                   curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
                   curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
                   curl_setopt($ch, CURLOPT_URL, $url);
                   curl_setopt($ch, CURLOPT_HTTPHEADER, Array( 'Content-Type: text/xml; charset=utf-8','Content-Length: '.strlen($XML),'SOAPAction: Services'));
                   curl_setopt($ch, CURLOPT_POST, 1);
                   curl_setopt($ch, CURLOPT_POSTFIELDS, $XML);                   


                   $postResult = curl_exec($ch);

                   $test= simplexml_load_string($postResult);

                  print_r($test); // I obtain nothing.

I obtain this string from the curl response:

 string(1128) "<?xml version="1.0" encoding="Windows-1252"?><ConsultaXMLout xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Respuestas><DatosIdiomas><DatosEnvios><Datos Idioma="1" Codigo="XXXXX0700005020128012D" Evento="1" web_id="Sin web_id"><Estado>Información sobre su envío no disponible. Compruebe si es correcto.</Estado><Descripcion>La información sobre su envío todavía no está disponible. Por favor, realice su consulta transcurridos unos días.</Descripcion><Fecha /></Datos></DatosEnvios></DatosIdiomas></Respuestas></ConsultaXMLout>" 

Thank you in advance!

Funereal
  • 653
  • 2
  • 11
  • 32
  • What tool or library are you using to parse the XML? – cxw Mar 16 '15 at 15:25
  • @cxw Im doing simplexml_load_string($string); – Funereal Mar 16 '15 at 15:26
  • please post an example of the code that is invoking curl and that is calling simplexml. You might be having problems with quoting or something else not obvious from the question as it stands. Thanks! – cxw Mar 16 '15 at 15:32
  • This `</` is not valid XML. – TiMESPLiNTER Mar 16 '15 at 15:41
  • @devtreat thanks for posting the code. Would you please try Example #1 at http://php.net/manual/en/simplexml.examples-errors.php (also print `$error->column`) and post the results? That may help localize the error. – cxw Mar 16 '15 at 20:05
  • @cxw It dont show nothing :/ – Funereal Mar 17 '15 at 15:42
  • @devtreat - That's good - it means your parse worked. I posted an answer below. – cxw Mar 17 '15 at 16:10

3 Answers3

1

You're doing a somewhat common (but easy to prevent) mistake in the code: The XML is created "by hand" as writing a string. Even thought this is possible, this is also very error prone.

The XML you provide in your question is with many errors and neither well-formed nor valid. If you want to learn more about these two terms, please see Is there a difference between 'valid xml' and 'well formed xml'? (Sep 2008).

This shows the errors your string produces when loaded into a DOMDocument or a SimpleXMLElement:

#001    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
#002                        xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
#003                        <soap:Body>
#004                        <Consult Localitation xmlns="Services/">
[FATAL]                                         ^- (41) Specification mandate value for attribute Localitation (4:41)
[FATAL]                                         ^- (65) attributes construct error (4:41)
[FATAL]                                         ^- (73) Couldn't find end of Start Tag Consult line 4 (4:41)
#005                        <XMLin>
#006                        &lt;ConsultXMLin Language=&quot;1&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;
#007                        &lt;Consult&gt;
#008                        &lt;Code&gt;XXXXX0700005020128012D&lt;/Code&gt;
#009                        &lt;/Consult&gt;
#010                        &lt;/ConsultXMLin&gt;</XMLin>
#011                        </Consult Localitation></soap:Body>
[FATAL]                              ^                        ^- (76) Opening and ending tag mismatch: Envelope line 1 and Body (11:55)
[FATAL]                              ^- (73) expected '>' (11:30)
[FATAL]                              ^- (76) Opening and ending tag mismatch: Body line 3 and Consult (11:30)
#012                        </soap:Envelope>
[FATAL]                     ^- (5) Extra content at the end of the document (12:21)

Instead of creating the SOAP XML via a string, you can make use of existing libraries like SimpleXML or - as this is Soap related - SoapClient.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • I thought the OP was asking why `postResult` didn't parse. What's the error dump for that? Is it a namespace/schema problem? – cxw Mar 17 '15 at 00:42
  • I'm just being lazy since I'm not at a console :) . I think your point about using tools to generate the XML is very well made. – cxw Mar 17 '15 at 01:06
1

The problem is that print_r doesn't do well at displaying the output of simplexml parsing. Full credit to @Josh Davis and @hakre, who discuss this at this answer. Try

print_r($test->xpath("//Estado"))

and you should get the contents of the <Estado> tag. See examples from the PHP manual for more ways to retrieve the content.

Community
  • 1
  • 1
cxw
  • 16,685
  • 2
  • 45
  • 81
0

Finally I found the solution.

// String to extract string from.

  string(1128) "<?xml version="1.0" encoding="Windows-1252"?><ConsultaXMLout xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Respuestas><DatosIdiomas><DatosEnvios><Datos Idioma="1" Codigo="XXXXX0700005020128012D" Evento="1" web_id="Sin web_id"><Estado>Información sobre su envío no disponible. Compruebe si es correcto.</Estado><Descripcion>La información sobre su envío todavía no está disponible. Por favor, realice su consulta transcurridos unos días.</Descripcion><Fecha /></Datos></DatosEnvios></DatosIdiomas></Respuestas></ConsultaXMLout>";

I used htmlspecialchars of the response, then I obtained the full code.

// Call the function.
echo extractString($string, '<XmlIn>', '</Xmlin>'); 

// Here I taked all the code inside these two tags with the function extractString.

// Function that returns the string between two strings.
function extractString($string, $start, $end) {
$string = " ".$string;
$ini = strpos($string, $start);
if ($ini == 0) return "";
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);

And this is the function that gets the content between two tags.

I hope that it will be usefull ;)

Funereal
  • 653
  • 2
  • 11
  • 32