1

Before someone points out that there are a ton of similar questions like this, please keep in mind I have tried and exhausted all methods I could find here on stacked.

I'm having trouble using simplexml to pull out the data I want from a response that is structured like this.

<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>
  <authenticateresponse xmlns="http://somesite.co.nz">
    <authenticateresult>
      <username>Username</username>
      <token>XXXXXXXXX</token>
      <reference>
        <message>Access Denied</message>
      </reference>
    </authenticateresult>
  </authenticateresponse>
</soap:body>

In this case I'd like to know how to pull out the token and username.

Duncan
  • 226
  • 1
  • 11
  • 1
    Very likely, the *default namespace* (`xmlns="http://somesite.co.nz"`) causes you the problem. Read : http://stackoverflow.com/a/2386706/2998271 – har07 Apr 26 '16 at 11:32

1 Answers1

1

Your XML has default namespace declared at authenticateresponse element :

xmlns="http://somesite.co.nz"

Notice that the element where default namespace is declared along with the descendant elements without prefix are in the same namespace. To access element in default namespace, you need to map a prefix to the namespace URI and use the prefix in the XPath, for example :

$raw = <<<XML
<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>
  <authenticateresponse xmlns="http://somesite.co.nz">
    <authenticateresult>
      <username>Username</username>
      <token>XXXXXXXXX</token>
      <reference>
        <message>Access Denied</message>
      </reference>
    </authenticateresult>
  </authenticateresponse>
</soap:body>
</soap:envelope>
XML;
$xml = new SimpleXMLElement($raw);
$xml->registerXPathNamespace('d', 'http://somesite.co.nz');
$username = $xml->xpath('//d:username');
echo $username[0];

eval.in demo

output :

Username

A few former related questions :

Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
  • Thank you for this. I'm just going over some of those other questions. For some bizzare reason even when I rewrite my code exactly as you have done it is still failing, I'm getting an undefined offset on username. – Duncan Apr 26 '16 at 11:56
  • Could you post short demo, probably in eval.in, that reproduces the problem? Otherwise I have no idea... – har07 Apr 26 '16 at 12:05
  • Your solution works when I write it in statically, error has to be in the response data somewhere, I only posted a fraction of it here. Thanks for the help much appreciated. @har07 – Duncan Apr 26 '16 at 12:18