I'm trying to get the contents of the faultstring element and I'm more comfortable with SimpleXML's object syntax ($xml->...->faultstring.) The DomDocument method below works, but I'd prefer to stick with SimpleXML.

PHP version 5.6.40, Libxml 2.9.1.

$xmlResponse = '<?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>
            <soap:Fault>
                <faultcode>soap:Client</faultcode>
                <faultstring>Server did not recognize the value of HTTP Header SOAPAction: https://gw1.domain.com:4430/.</faultstring>
                <detail />
            </soap:Fault>
        </soap:Body>
    </soap:Envelope>';

// DOES NOT WORK
$xml = simplexml_load_string($xmlResponse,NULL,NULL,"http://schemas.xmlsoap.org/soap/envelope/");
$faultstring = (string) ($xml->Body->Fault->faultstring);
var_dump($faultstring);

// WORKS
$_DomObject = new DOMDocument;
$_DomObject->loadXML($xmlResponse);
if (!$_DomObject) die("Error while parsing the document");
$s = simplexml_import_dom($_DomObject);
foreach(['faultcode','faultstring','detail'] as $tag) {
    echo $tag.' => '.$_DomObject->getElementsByTagName($tag)[0]->textContent.'<br/>';
}

1 Answers

1
miken32 On Best Solutions
<?php
$xmlResponse = <<<XML
<?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>
        <soap:Fault>
            <faultcode>soap:Client</faultcode>
            <faultstring>Server did not recognize the value of HTTP Header SOAPAction: https://gw1.domain.com:4430/.</faultstring>
            <detail />
        </soap:Fault>
    </soap:Body>
</soap:Envelope>
XML;

XML namespaces are getting in the way; they're the soap: prefix on the element names. It's possible to register all the namespaces and get it working that way, but just using XPath is easier:

$xml = new SimpleXMLElement($xmlResponse);
$fault = $xml->xpath("//faultstring");
echo (string)$fault[0] . "\n";

And here's how it looks using namespaces. You still get the object syntax, but it becomes a lot more complicated.

$xml = new SimpleXMLElement($xmlResponse);
$fault = $xml->children("soap", true)->Body->children("soap", true)->Fault->children()->faultstring;
echo (string)$fault . "\n";

Output for both:

Server did not recognize the value of HTTP Header SOAPAction: https://gw1.domain.com:4430/.