Ravioli87
Ravioli87

Reputation: 835

Strip SOAP Envelope for Saving Response to XML File

I have a SOAP response that I want to save to an XML file. When the response is written to the file, the SOAP envelope is written with it, making the XML file useless due to the error:

XML declaration allowed only at the start of the document in ...

In this case, XML is being declared twice:

<?xml version="1.0" encoding="ISO-8859-1"?>
    <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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><ns1:NDFDgenResponse xmlns:ns1="http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl">
           <dwmlOut xsi:type="xsd:string">
           <?xml version="1.0"?>
           ...

Is there a good way to strip out this SOAP envelope and just save what's between it?

Here's how I'm writing the response to the file:

$toWrite = htmlspecialchars_decode($client->__getLastResponse());
$fp = fopen('weather.xml', 'w');
fwrite($fp, $toWrite);
fclose($fp);

Upvotes: 0

Views: 2393

Answers (1)

ThW
ThW

Reputation: 19512

The problem is the htmlspecialchars_decode(). The envelope document contains other XML documents as text nodes. If you decode the entities in the XML document you will destroy it. Never use htmlspecialchars_decode() on an XML document.

Load the (envelope) XML into a DOM and read the needed value from it.

$xml = <<<'XML'
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
  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>
    <ns1:NDFDgenResponse 
      xmlns:ns1="http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl">
      <dwmlOut xsi:type="xsd:string">
        &lt;?xml version="1.0"?>
        &lt;weather>XML&lt;/weather>
      </dwmlOut>
     </ns1:NDFDgenResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xpath->registerNamespace('ndfd', 'http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl');

$innerXml = $xpath->evaluate(
  'string(/soap:Envelope/soap:Body/ndfd:NDFDgenResponse/dwmlOut)'
);
echo $innerXml;

Output:

<?xml version="1.0"?>
<weather>XML</weather>

Upvotes: 0

Related Questions