-1

Good day.

I am having trouble being able to use the simplexml_load_string function on my xml response. The object is returned as empty.

Any clue?

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns2:signOnResponse xmlns:ns2="http://www.verimatrix.com/omi">
            <sessionHandle>
                <ns1:handle xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">gVwAFRVlyqRKgqk/u73Ifc3nGig=</ns1:handle>
            </sessionHandle>
            <result>
                <ns1:resultId xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">admin</ns1:resultId>
                <ns1:resultCode xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">0</ns1:resultCode>
                <ns1:resultText xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">Success</ns1:resultText>
            </result>
        </ns2:signOnResponse>
    </soapenv:Body>
</soapenv:Envelope>

Ultimately, I would like to parse the object to get the session handle info from ns1:handle

Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
Keith Roye
  • 17
  • 1
  • 7
  • What have you tried so far? Where are you stuck? – Nico Haase Apr 27 '21 at 18:24
  • I have tried loading that string into the function but it returns an empty object. Not sure why. – Keith Roye Apr 27 '21 at 18:28
  • Please share more details, like the code involved – Nico Haase Apr 27 '21 at 18:30
  • The response example is there. Can open any php client and run the simplexml_load_string function on that string and get the result, which will be empty – Keith Roye Apr 27 '21 at 18:34
  • Please share the code you are using. Don't let others guess which code you are using – Nico Haase Apr 27 '21 at 18:36
  • $validXML = simplexml_load_string($response); if ($validXML === false) { return null; } – Keith Roye Apr 27 '21 at 18:38
  • $response = the xml string I posted in the question – Keith Roye Apr 27 '21 at 18:38
  • I've tried your XML with the code you suggest and the XML loads OK. This is why you are being asked to show exactly what you do in the question. It helps us to be able to reproduce your issue, which at the moment I can't – Nigel Ren Apr 27 '21 at 18:52
  • Please edit your question to contain **all** relevant information, like the code involved. Please do not share such relevant information hidden in the comment section. Also, could it be possible that `$response` is part of any API call? – Nico Haase Apr 27 '21 at 19:03
  • PHP has an extension for SOAP: https://www.php.net/manual/de/class.soapclient.php – ThW Apr 27 '21 at 19:43

2 Answers2

0

You need to be aware of the namespaces while loading and traversing the document. Read up on simplexml_load_string and the SimpleXMLElement class.

<?php
$response = <<<END
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns2:signOnResponse xmlns:ns2="http://www.verimatrix.com/omi">
            <sessionHandle>
                <ns1:handle xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">gVwAFRVlyqRKgqk/u73Ifc3nGig=</ns1:handle>
            </sessionHandle>
            <result>
                <ns1:resultId xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">admin</ns1:resultId>
                <ns1:resultCode xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">0</ns1:resultCode>
                <ns1:resultText xmlns:ns1="http://www.verimatrix.com/schemas/OMItypes.xsd">Success</ns1:resultText>
            </result>
        </ns2:signOnResponse>
    </soapenv:Body>
</soapenv:Envelope>
END;

$unmarshalled = simplexml_load_string($response, null, null, 'soapenv', true);
if ($unmarshalled !== false)
{
    $handle = $unmarshalled->Body->children('ns2', true)->signOnResponse->children()->sessionHandle->children('ns1', true)->handle;
    
    assert($handle=='gVwAFRVlyqRKgqk/u73Ifc3nGig=', 'Handle should be gVwAFRVlyqRKgqk/u73Ifc3nGig=');
    
    echo 'Handle is: '.$handle.PHP_EOL;
}
else
{
    echo 'Invalid XML'.PHP_EOL;
}
Rob Ruchte
  • 3,569
  • 1
  • 16
  • 18
0

It's quite a common trap to fall into: The object returned by e.g. simplexml_load_string appears to be empty on var_dump() when in fact it isn't (by the way, it's not even an object, but a resource).

Let's try to prove this by fetching some nodes out of your document. As a big fan of XPath, I'm going to use XPath expressions for that, but first we'll have to deal with the namespaces:

$xml = simplexml_load_string($xml);

// Get all namespaces 
$namespaces = $xml->getNamespaces(true); 

// Register them so XPath knows about them  
foreach ($namespaces as $prefix => $url) {

    $xml->registerXPathNamespace($prefix, $url);
}

With that out of the way, we can go ahead and fetch some nodes:

// Grab all nodes with a namespace of 'ns1'. To just get the node
// you're after, you could just say $xml->xpath('//ns1:handle').
$query = $xml->xpath('//ns1:*');

// Prepare to collect some infos about our fetched nodes (if any).  
$collect = [];

// Loop the result set given by XPath, if any. 
foreach ($query as $node) {

    $collect[] = [

        // Name of the node without namespace prefix, e.g. 'resultId' 
        $node->getName(), 

        // Value, e.g. 'admin'
        (string) $node, 

        // Namespace, e.g. 'ns1'
        $node->getNamespaces()  
    ];
}

Now, when your dumping collect you're dumping an actual array with actual values. And it's not empty.

References:

nosurs
  • 680
  • 6
  • 13