PHP WSDL 响应作为对象

PHP WSDL response as object

我正在向 PHP(下面的代码)中的 WSDL 发送响应请求。响应的结构方式让我不确定如何从中提取数据。它作为一个对象返回,里面有 XML。是否有解析此对象的 XML 的标准方法?

这是我的代码:

<?php

    $wsdl="http://192.168.0.31/WSSmartConnect/cCustomerDocument.asmx?wsdl";

    $companyID=1;
    $sysUser='dburchfield';
    $accountNum=$_POST['accountNum'];
    $trxUniqueKey=0;
    $startDate=$_POST['startDate'];
    $endDate=$_POST['endDate'];
    $documentType=$_POST['documentType'];
    $tankNum=0;
    $serviceNum=0;
    $locationNum=0;


    $param=array(
      'pCompanyID'=>$companyID,
      'pSysUser'=>$sysUser,
      'pAccountNum'=>$accountNum,
      'pTrxUniqueKey'=>$trxUniqueKey,
      'pFromDate'=>$startDate,
      'pToDate'=>$endDate,
      'pDocumentType'=>$documentType,
      'pTankNum'=>$tankNum,
      'pServiceNum'=>$serviceNum,
      'pLocationNum'=>$locationNum
    );

    $client = new SoapClient($wsdl, array('trace' => 1));

    $soapCall = $client->LoadCustomerDocuments($param);

    //$response = $client->__getLastResponse();

    echo "<strong>" . $startDate . " - " . $endDate . "</strong><br><br>";
    var_dump($soapCall);

?>

这是我得到的回复。如何拉出 XML 并解析键?

C:\wamp64\www\E3Portal\smartConnect.php:85:
object(stdClass)[2]
  public 'LoadCustomerDocumentsResult' => 
    object(stdClass)[3]
      public 'any' => string '<xs:schema xmlns:mstns="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" xmlns="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="DSCustomerDocumentInfo" targetNamespace="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" attributeFormDefault="qualified" elementFormDefault="qualified"><xs:element name="DSCustomerDocumentInfo" msdata:IsDataSet="true" msdata:Us'... (length=6063)

这是我在使用 SoapUI 时得到的 WSDL 响应:

<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:Body>
      <LoadCustomerDocumentsResponse xmlns="http://www.addsys.com/">
         <LoadCustomerDocumentsResult>
            <xs:schema id="DSCustomerDocumentInfo" targetNamespace="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:mstns="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" xmlns="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
               <xs:element name="DSCustomerDocumentInfo" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                  <xs:complexType>
                     <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="CustomerDocumentInfo">
                           <xs:complexType>
                              <xs:sequence>
                                 <xs:element name="doc_type" type="xs:short" minOccurs="0"/>
                                 <xs:element name="doc_id" type="xs:int" minOccurs="0"/>
                                 <xs:element name="doc_date" type="xs:dateTime" minOccurs="0"/>
                                 <xs:element name="has_print_info" type="xs:int" minOccurs="0"/>
                                 <xs:element name="tank_num" type="xs:short" minOccurs="0"/>
                                 <xs:element name="service_num" type="xs:short" minOccurs="0"/>
                                 <xs:element name="location_num" type="xs:short" minOccurs="0"/>
                                 <xs:element name="doc_type_desc" type="xs:string" minOccurs="0"/>
                              </xs:sequence>
                           </xs:complexType>
                        </xs:element>
                     </xs:choice>
                  </xs:complexType>
               </xs:element>
            </xs:schema>
            <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
               <DSCustomerDocumentInfo xmlns="http://www.addsys.com/CustomerDocument/DSCustomerDocumentInfo.xsd">
                  <CustomerDocumentInfo diffgr:id="CustomerDocumentInfo1" msdata:rowOrder="0">
                     <doc_type>23</doc_type>
                     <doc_id>506342</doc_id>
                     <doc_date>2021-01-04T00:00:00-06:00</doc_date>
                     <has_print_info>1</has_print_info>
                     <tank_num>0</tank_num>
                     <service_num>0</service_num>
                     <location_num>1</location_num>
                     <doc_type_desc>WDMS Invoices</doc_type_desc>
                  </CustomerDocumentInfo>
                  <CustomerDocumentInfo diffgr:id="CustomerDocumentInfo2" msdata:rowOrder="1">
                     <doc_type>23</doc_type>
                     <doc_id>509603</doc_id>
                     <doc_date>2021-01-07T00:00:00-06:00</doc_date>
                     <has_print_info>1</has_print_info>
                     <tank_num>0</tank_num>
                     <service_num>0</service_num>
                     <location_num>1</location_num>
                     <doc_type_desc>WDMS Invoices</doc_type_desc>
                  </CustomerDocumentInfo>
               </DSCustomerDocumentInfo>
            </diffgr:diffgram>
         </LoadCustomerDocumentsResult>
      </LoadCustomerDocumentsResponse>
   </soap:Body>
</soap:Envelope>

看起来你的 $soapCall->LoadCustomerDocumentsResult->any 包含有效的 XML,所以你可以使用任何内置 XML 类:

$my_result_var = new SimpleXMLElement($soapCall->LoadCustomerDocumentsResult->any);

$reader = new XMLReader();
$reader->XML($soapCall->LoadCustomerDocumentsResult->any);
$reader->read();

或者你可以试试 composer 的助手 类 - 比如 phpro/soap-client

更新: 好的,所以你的 xml 比平时复杂一点,所以这里有一些提示:

  1. 要使您的 xml 有效,您只需要一个外部元素,所以
    "<xml>" . $soapCall->LoadCustomerDocumentsResult->any . "</xml>"

会修复它。

  1. 您的第二个元素中有不寻常的命名空间。要使其工作,您需要使用 registerXPathNamespace 函数:
  $my_result_var = new SimpleXMLElement("<xml>" . $soapCall->LoadCustomerDocumentsResult->any . "</xml>");
  $my_result_var->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-diffgram-v1');

接下来您需要通过命名空间获取您的元素:

$diffgram = $my_result_var->xpath("//d:diffgram");
foreach($diffgram[0]->DSCustomerDocumentInfo->CustomerDocumentInfo as $docInfo) {
     var_dump($docInfo->doc_id);
}

实际上在 $diffgram[0] 之后,您可以像常规一样使用第二个元素 xml.

希望对您有所帮助。