Solved

Retrieve element from SimpleXMLElement returning nothing

Posted on 2014-10-13
3
165 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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Suggested Solutions

Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

785 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