Andy
Andy

Reputation: 2140

Soap response can't be parsed with SimpleXML

I'm using the native soapclient() to call a WSDL but I can't use simplexml to parse the result. I consistently get an error:

Warning: simplexml_load_string() [function.simplexml-load-string]: 
Entity: line 1: parser error : Extra content at the end of the document

This doesn't look like a namespace problem and I have already tried the patch mentioned elsewhere on the site to remove colons from the input string.

EDIT:

Thanks, Gordon

Yes you're right. The server is a Microsoft site using datasets.

If I declare the soap client with trace set to true:

$soapClient = new soapclient($this->wsdlUrl,array('trace'=>true));

and then retrieving the raw XML from the response:

$soapResult = $soapClient->GetScheduledSectors();
$responseXml = $soapClient->__getLastResponse();
$xml = simplexml_load_string($responseXml, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");

then I get:

SimpleXMLElement Object
(
    [Body] => SimpleXMLElement Object
        (
        )
)

The response XML header and first tag looks like this:

<?xml version='1.0'?> 
<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>

  <GetScheduledSectorsResponse xmlns="https://www.kulula.com/k3api/">

     <GetScheduledSectorsResult msdata:SchemaSerializationMode="ExcludeSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

        <xs:schema id="dsFlight" targetNamespace="http://tempuri.org/dsFlight.xsd" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:mstns="http://tempuri.org/dsFlight.xsd" xmlns="http://tempuri.org/dsFlight.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">

           <xs:element name="dsFlight" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:ExecutionTime="1140">

              <xs:complexType>

                 <xs:choice minOccurs="0" maxOccurs="unbounded"/>

              </xs:complexType>

           </xs:element>

        </xs:schema>

        <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

           <dsFlight xmlns="http://tempuri.org/dsFlight.xsd">

              <FlightSector diffgr:id="FlightSector1" msdata:rowOrder="0">

                 <FlightSectorId>1</FlightSectorId>

                 <FlightSectorName>JNBCPT</FlightSectorName>

                 <FromAirport>O.R. Tambo (Jo'burg)</FromAirport>

                 <ToAirport>Cape Town</ToAirport>

                 <DepartureAirportId>1</DepartureAirportId>

                 <ArrivalAirportId>2</ArrivalAirportId>

                 <AirlineCode>BA</AirlineCode>

                 <Ordernumber>100</Ordernumber>

                 <FlightZoneId>1</FlightZoneId>

                 <DepartureCountryCode>ZA</DepartureCountryCode>

                 <DepartureContinentCode>AF</DepartureContinentCode>

              </FlightSector>

I have also tried to register the following namespaces:

$xml = simplexml_load_string($this->responseXml, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
    $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
    $xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
    $xml->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
    $xml->registerXPathNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1');
    $xml->registerXPathNamespace('mstns', 'http://tempuri.org/dsFlight.xsd');
    $xml->registerXPathNamespace('msprop', 'urn:schemas-microsoft-com:xml-msprop');

but still get an empty object in $xml

Upvotes: 4

Views: 7200

Answers (3)

yariv_kohn
yariv_kohn

Reputation: 92

I also encounter this issue. After contacting the Web Service developer I got the answer that this response is not a XML, but DATATABLE (which is a c# datatype).

Finally my solution was to create my own parser, instead of using native PHP ones.

Try using explode() according to the relevant fields. I'm know this is not the best solution (definitely not best practice), However if you can't get it in another format this might work for you.

Upvotes: 0

Iron Hoang
Iron Hoang

Reputation: 179

I have same problem, then i try:

$soapResult = $soapClient->GetScheduledSectors();
$responseXml = $soapClient->__getLastResponse();

$dom = new DomDocument();
$dom->loadXML($responseXml );

$phpObject = simplexml_load_string($dom->textContent);
print_r($phpObject ); 

And see the results.

Upvotes: 0

Reid Johnson
Reid Johnson

Reputation: 1394

You might try DOMDocument instead of simpleXML as it has seemed a bit more fault tolerent in my past usage. Not nearly as fast though.

When I needed to parse SOAP, however, I refferred to How to parse SOAP XML? and found excellent information on the PHP 5 native Soap client.

Upvotes: 1

Related Questions