Search code examples
phpsoapsimplexml

How to Parse SOAP response and extract part of it using simpleXml in php


I am trying to parse the following SOAP response

  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <ns1:CommandResponseData xmlns:ns1="http://example.com/ossbss/charge.once/wsdl/entity/Tis/xsd/1">
         <ns1:CommandResult>
            <ns1:TransactionResult>
               <ns1:OperationResult>
                  <ns1:Operation name="Read" modifier="Customer">
                    ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="VersionRead" modifier="Customer">
                     <ns1:ParameterList>
                      ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="BucketRead" modifier="Customer">
                     <ns1:ParameterList>
                      ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="Read" modifier="ROP">
                    ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="VersionRead" modifier="ROP">
                     <ns1:ParameterList>
                        <ns1:StringParameter name="CustomerId">91777888888</ns1:StringParameter>
                        <ns1:IntParameter xsi:type="ns1:IntParameter" name="Key" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</ns1:IntParameter>
                        <ns1:DateTimeParameter name="vValidFrom">2017-12-18T18:21:49.000</ns1:DateTimeParameter>
                        <ns1:EnumerationValueParameter name="category">ONLINE</ns1:EnumerationValueParameter>
                        <ns1:SymbolicParameter name="vInvalidFrom">MAX_DATEANDTIME</ns1:SymbolicParameter>
                        <ns1:ListParameter name="BasicTariffBlocking">
                           <ns1:StringElement>FBC</ns1:StringElement>
                           <ns1:StringElement>FBC</ns1:StringElement>
                        </ns1:ListParameter>
                        <ns1:StructParameter name="OnPeakAccountID">
                           <ns1:IntParameter xsi:type="ns1:IntParameter" name="Precision" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</ns1:IntParameter>
                        </ns1:StructParameter>
                        <ns1:StringParameter name="s_OfferId">AWCCUG</ns1:StringParameter>
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="BucketRead" modifier="ROP">
                    ....
                    ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="Read" modifier="RPP">
                     <ns1:ParameterList>
                       ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="VersionRead" modifier="RPP">
                    ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="BucketRead" modifier="RPP">
                    ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                  <ns1:Operation name="Read" modifier="RPP">
                     <ns1:ParameterList>
                       ....
                     </ns1:ParameterList>
                  </ns1:Operation>
                 ....

                  <ns1:Operation name="Read" modifier="PCP">
                     <ns1:ParameterList>
                      ....
                     </ns1:ParameterList>
                  </ns1:Operation>
             
               </ns1:OperationResult>
            </ns1:TransactionResult>
         </ns1:CommandResult>
      </ns1:CommandResponseData>
   </soapenv:Body>
</soapenv:Envelope>

from all this huge SOAP response, I am trying to extract only the content of any node that contains name="Read" and Modifier="RPP" : <ns1:Operation name="Read" modifier="RPP">

Like the below node:

<ns1:Operation name="Read" modifier="RPP">
                     <ns1:ParameterList>
                        <ns1:StringParameter name="CustomerId">91777888888</ns1:StringParameter>
                        <ns1:IntParameter xsi:type="ns1:IntParameter" name="OfferProfileKey" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</ns1:IntParameter>
                        <ns1:IntParameter xsi:type="ns1:IntParameter" name="Key" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">3</ns1:IntParameter>
                        <ns1:EnumerationValueParameter name="category">ONLINE</ns1:EnumerationValueParameter>
                        <ns1:IntParameter xsi:type="ns1:IntParameter" name="prefetchFilter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">-1</ns1:IntParameter>
                        <ns1:LongParameter xsi:type="ns1:LongParameter" name="s_ActivationEndTime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1924975800000</ns1:LongParameter>
                        <ns1:LongParameter xsi:type="ns1:LongParameter" name="s_ActivationStartTime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1480378734000</ns1:LongParameter>
                        <ns1:StringParameter name="s_CRMTitle">-</ns1:StringParameter>
                        <ns1:BooleanParameter name="s_CanBeSharedByMultipleRops">false</ns1:BooleanParameter>
                        <ns1:BooleanParameter name="s_InsertedViaBatch">false</ns1:BooleanParameter>
                        <ns1:StringParameter name="s_PackageId">CUG</ns1:StringParameter>
                        <ns1:BooleanParameter name="s_PreActive">false</ns1:BooleanParameter>
                     </ns1:ParameterList>

and featch parts its content like:

<ns1:IntParameter xsi:type="ns1:IntParameter" name="Key" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">3</ns1:IntParameter>
  <ns1:StringParameter name="s_PackageId">CUG</ns1:StringParameter>

the desired output is:

['key'] = 3
['s_PackageId'] = 'CUG'

Below is my coding attempts:

$xml = simplexml_load_string( $re, 'SimpleXMLElement', LIBXML_NOCDATA);//LIBXML_NOCDATA LIBXML_NOWARNING);

$posts = $xml->children('soapenv', true)->Body->children('ns1', true)->CommandResponseData
    ->CommandResult->TransactionResult->OperationResult;
 foreach($posts->children('ns1', true) as $child) {
     $role =$child->attributes();
     foreach($child as $key => $value) {

         if($role['name'] == "Read" && $role['modifier'] == "RPP") {
              $c = $child->children('ns1', true)->children('ns1', true);
             foreach($c->attributes() as $key => $value) {

                echo $key;
                echo $value;

with this code i am not able to get the disired output. instead, i am getting SimpleXml object with data types like shown on the below Image enter image description here


Solution

  • I prefer xpath for such tasks.

    $xml = new SimpleXMLElement($re);
    $xml->registerXPathNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
    $xml->registerXPathNamespace("ns1", "http://example.com/ossbss/charge.once/wsdl/entity/Tis/xsd/1");
    $readRppOperations = $xml->xpath("/soapenv:Envelope/soapenv:Body/ns1:CommandResponseData/ns1:CommandResult/ns1:TransactionResult/ns1:OperationResult/ns1:Operation[@name='Read' and @modifier='RPP']/ns1:ParameterList");
    foreach ($readRppOperations as $operation) {
      $key = $operation->xpath("ns1:IntParameter[@name='Key']");
      $packId = $operation->xpath("ns1:StringParameter[@name='s_PackageId']");
      if ($key) {
        echo "Key: " . $key[0] . PHP_EOL;
      }
      if ($packId) {
        echo "s_PackageId: " . $packId[0] . PHP_EOL;
      }
    }