如何在 php 中使用 simpleXml 解析 SOAP 响应并提取其中的一部分

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

我正在尝试解析以下 SOAP 响应

  <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>

从所有这些巨大的 SOAP 响应中,我试图只提取包含 name="Read"Modifier="RPP" 的任何节点的内容: <ns1:Operation name="Read" modifier="RPP">

喜欢下面的节点:

<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>

并提取其内容的部分,例如:

<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>

所需的输出是:

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

以下是我的编码尝试:

$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;

使用此代码,我无法获得所需的输出。相反,我得到的 SimpleXml 对象的数据类型如下图所示

我更喜欢 xpath 执行此类任务。

$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;
  }
}