Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Retrieve element from SimpleXMLElement returning nothing

Posted on 2014-10-13
3
166 Views
Last Modified: 2014-10-14
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.
0
Comment
Question by:Kevin Cabral
3 Comments
 
LVL 34

Accepted Solution

by:
Beverley Portlock earned 250 total points
ID: 40378595
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
 
LVL 109

Assisted Solution

by:Ray Paseur
Ray Paseur earned 250 total points
ID: 40378717
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
 
LVL 17

Expert Comment

by:Chris Harte
ID: 40379820
0

Featured Post

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Redirect 301 from one address  to another 5 25
Powershell import xml to array (non-cli xml) 4 18
How do I show metrics with PHP or Javascript 6 33
JQuery Search Filter 2 32
Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question