Retrieve element from SimpleXMLElement returning nothing

Hello everyone,

I have this sample XML below

<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:header>
    <authorizationtoken ns="test">
      <token>cab1f8aa-1c21-4c28-a24e-8be101ac6d75</token>
    </authorizationtoken>
  </soap:header>
  <soap:body>
    <webindividualinsertresponse ns="test">
      <webindividualinsertresult>
        <currentkey>dataIWANT</currentkey>
      </webindividualinsertresult>
    </webindividualinsertresponse>
  </soap:body>
</soap:envelope>

I'm trying to retrieve a particular field, theres only 1 but nothing is coming back after parsing the xml.

$response = $client->__doRequest($request, $url, "namespace", 1);
$response = str_replace('xmlns=', 'ns=', $response); //otherwise xpath wont work turn xmlns to ns on the string

$myXml = new SimpleXMLElement($response);
print_r($myXml->asXML());
$curKeyArray = $myXml->xpath('//currentkey[1]');

any thoughts.
Kevin CabralSoftware DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Beverley PortlockCommented:
SimpleXML does not like ':' so I have simply removed the "soap:" prefix and then used a cast to force the output like so...

<?php

$data = <<<DOC
<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:header>
    <authorizationtoken ns="test">
      <token>cab1f8aa-1c21-4c28-a24e-8be101ac6d75</token>
    </authorizationtoken>
  </soap:header>
  <soap:body>
    <webindividualinsertresponse ns="test">
      <webindividualinsertresult>
        <currentkey>dataIWANT</currentkey>
      </webindividualinsertresult>
    </webindividualinsertresponse>
  </soap:body>
</soap:envelope>
DOC;

// Simple XML hates ':'
//
$cleanedXml = str_replace('soap:', '', $data);

$xml = simplexml_load_string( $cleanedXml );

// Cast to a string
//
echo (string) $xml->body->webindividualinsertresponse->webindividualinsertresult->currentkey;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
Interestingly, PHP does not handle this namespace well.  I've been able to get namespaces from a lot of XML strings, but not this one.  PHP SOAP support is not very good -- for example, identical variable names in different namespaces collide.  The whole point of using namespaces is to avoid the collision.  There is a PHP bug report on this, but it's five years old, suggesting that PHP will never fix it.  And nobody uses SOAP anymore since there are RESTful interfaces everywhere.  You might want to ask the publisher about a RESTful interface and a JSON string -- that's the popular way to communicate in this millennium!

Same idea, only slightly different implementation.  This is a more generalized way of dealing with unwanted namespaces.
http://iconoun.com/demo/temp_guardianoflight.php

<?php // demo/temp_guardianoflight.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28536786.html

// A FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE
function mungXML($xml, $key='soap')
{
    // A REGULAR EXPRESSION TO MUNG THE XML
    $rgx
    = '#'               // REGEX DELIMITER
    . '('               // GROUP PATTERN 1
    . '\<'              // LOCATE A LEFT WICKET
    . '/?'              // MAYBE FOLLOWED BY A SLASH
    . preg_quote($key)  // THE NAMESPACE
    . ')'               // END GROUP PATTERN
    . '('               // GROUP PATTERN 2
    . ':{1}'            // A COLON (EXACTLY ONE)
    . ')'               // END GROUP PATTERN
    . '#'               // REGEX DELIMITER
    ;
    // INSERT THE UNDERSCORE INTO THE TAG NAME
    $rep
    = '$1'          // BACKREFERENCE TO GROUP 1
    . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
    ;
    // PERFORM THE REPLACEMENT
    $xml =  preg_replace($rgx, $rep, $xml);

    return $xml;
}

// TEST DATA FROM THE POST AT E-E
$xml = <<<EOD
<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:header>
    <authorizationtoken ns="test">
      <token>cab1f8aa-1c21-4c28-a24e-8be101ac6d75</token>
    </authorizationtoken>
  </soap:header>
  <soap:body>
    <webindividualinsertresponse ns="test">
      <webindividualinsertresult>
        <currentkey>dataIWANT</currentkey>
      </webindividualinsertresult>
    </webindividualinsertresponse>
  </soap:body>
</soap:envelope>
EOD;

// ADD THE XML TAG
$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . $xml;

// DISPOSE OF THE NAMESPACE AND MAKE AN OBJECT
$new = mungXML($xml);
$obj = SimpleXML_Load_String($new);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// FIND THE DATA IN THE OBJECT
foreach ($obj->soap_body->webindividualinsertresponse->webindividualinsertresult as $wii_result)
{
    echo $wii_result->currentkey;
}

Open in new window

0
Chris HarteThaumaturgeCommented:
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.