1

I have the following XML ( you can say SOAP request ) :

<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
    <SOAPENV:Header>
        <NS:myHeader>
            <NS:SourceID>223423</NS:SourceID>
        </NS:myHeader>
    </SOAPENV:Header>
</SOAPENV:Envelope>

I use the following code and it works fine :

<?php 
$myRequest ='<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
   <SOAPENV:Header>
      <NS:myHeader>
         <NS:SourceID>223423</NS:SourceID>
      </NS:myHeader>
   </SOAPENV:Header>
   </SOAPENV:Envelope>';
$xml = simplexml_load_string($myRequest, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$namespaces = $xml->getNameSpaces(true);

$soapHeader = $xml->children($namespaces['SOAPENV'])->Header;
$myHeader = $soapHeader->children($namespaces['NS'])->myHeader;
echo (string)$myHeader->SourceID;
?>

The Problem

I know the prefix ( SOAPENV + NS ) , but the clients could change the prefix to whatever they want, so they may send me xml document that has ( MY-SOAPENV + MY-NS) prefixes.

My Question

How can I handle this since the namespace prefixes are not static , how can I parse it ?

Thanks

3
  • 2
    Namespaces are defined by uri and not by alias. I'm not sure about simplexml, but DomDocument can handle this just fine. Commented Jun 26, 2013 at 10:17
  • @Jack you are right , I've just switched to DOM Commented Jun 26, 2013 at 10:38
  • Yes, prefixes can be changed. And no, this is not a problem. Because the actual Namespace is defined by the URI, which does not change. Commented Jun 29, 2013 at 9:11

2 Answers 2

5

Here is the other way. We can dynamically parse the data as follows.

$myRequest ='<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
           <SOAPENV:Header>
              <NS:myHeader>
                 <NS:SourceID>223423</NS:SourceID>
              </NS:myHeader>
           </SOAPENV:Header>
           </SOAPENV:Envelope>';


$xml        = simplexml_load_string(
    $myRequest, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/"
);
$namespaces = $xml->getNameSpaces(true);
$prefix     = array_keys($namespaces); // we getting all namespaces here. According 
                                       // to that we can find datas.
$soapHeader = $xml->children($namespaces[$prefix[0]])->Header;
$myHeader   = $soapHeader->children($namespaces[$prefix[1]])->myHeader;
echo (string)$myHeader->SourceID;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Neil , I applied that and it works fine , I appreciate your help.
3

You should use DOM - personally I believe this is true for the general case because "simple XML" is an oxymoron, but I know others disagree. It is certainly true when dealing with a complex document tree like SOAP.

DOM provides getElementsByTagNameNS() (and other relevant NS-targeting methods) which allow you to specifiy the namespace URI (i.e. the thing that should remain static and be known ahead of time) instead of being specific about the prefix.

$soapNsUri = 'http://schemas.xmlsoap.org/soap/envelope/';
$myNsUri = 'http://xyz.gov/headerschema';

$doc = new DOMDocument;
$doc->loadXML($myRequest);

$header = $doc->getElementsByTagNameNS($soapNsUri, 'Header')->item(0);
$myHeader = $header->getElementsByTagNameNS($myNsUri, 'myHeader')->item(0);
$sourceID = $myHeader->getElementsByTagNameNS($myNsUri, 'SourceID')->item(0);

echo $sourceID->firstChild->data;

See it working

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.