PHP SoapClient不会向所有元素添加命名空间

时间:2017-11-16 10:05:00

标签: php xml web-services soap namespaces

我正在使用带有WSDL的PHP​​ Soap Client来发送soap请求。 这就是我初始化SoapClient的方式:

$options = [
      "trace" => 1,
      "login" => "Universal API/uAPI3170205802-sdv3r34",
      "password" => "U^#3@$dfw2",
      "classmap" => [ 
              "BookingDisplayRsp" => "BookingAirSegmentRsp"
      ],
];
$this->soapClient = new \SoapClient("BookingAirPnrElement.wsdl",$options);
$request = [
    "BookingAirPnrElementReq" => [
        "AuthorizedBy" => 'user',
        "SessionKey" => 'e6a30377-0956-4ac4-947d-b4ccb6641629',
        "BillingPointOfSaleInfo" => [
            "OriginApplication" => "uAPI"
        ],
        "AddAirPnrElement" => [
            "LoyaltyCard" => [
                "SupplierCode" => "DL",
                "CardNumber" => "23434523"
            ]
        ],
        "TargetBranch" => "P878183",
    ]
];

做肥皂请求:

 $response = $this->soapClient->__soapCall('service', $request);

我收到肥皂故障:

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <SOAP:Fault>
      <faultcode>Server.Data</faultcode>
      <faultstring>Error unmarshalling message body: Expected " {http://www.travelport.com/schema/sharedBooking_v41_0}BookingAirPnrElementReq" end tag, found "AddAirPnrElement" start tag (line 21, col 25, in UTF-8)</faultstring>
     <detail>
        <common_v41_0:ErrorInfo xmlns:common_v41_0="http://www.travelport.com/schema/common_v41_0">
           <common_v41_0:Code>1005</common_v41_0:Code>
           <common_v41_0:Service>WEBSVC</common_v41_0:Service>
           <common_v41_0:Type>Data</common_v41_0:Type>
           <common_v41_0:Description>Unable to parse XML stream</common_v41_0:Description>
           <common_v41_0:TransactionId>C42964360A07425CB318E5F570EEE3DC</common_v41_0:TransactionId>
        </common_v41_0:ErrorInfo>
     </detail>
   </SOAP:Fault>
 </SOAP:Body>

SoapClient生成的XML请求:

<?xml version="1.0" encoding="UTF-8"?>
  <SOAP-ENV:Envelope xmlns:SOAP ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.travelport.com/schema/common_v41_0" xmlns:ns2="http://www.travelport.com/schema/sharedBooking_v41_0">
    <SOAP-ENV:Header>
      <h:SessionContext xmlns:h="http://www.travelport.com/soa/common/security/SessionContext_v1" xmlns="http://www.travelport.com/soa/common/security/SessionContext_v1">
        <SessTok id="9444dc84-87c9-4563-80ab-a5f6475bfbe9"/>
      </h:SessionContext>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
      <ns2:BookingAirPnrElementReq AuthorizedBy="user" TargetBranch="P878183" SessionKey="9444dc84-87c9-4563-80ab-a5f6475bfbe9">
        <ns1:BillingPointOfSaleInfo OriginApplication="uAPI"/>
        <AddAirPnrElement>
          <ns1:LoyaltyCard CardNumber="23434523" SupplierCode="DL"/>
        </AddAirPnrElement>
        </ns2:BookingAirPnrElementReq>
    </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>

正如您所看到的, AddAirPnrElement 元素没有与 xmlns:ns2 =“http://www.travelport.com相对应的名称空间 ns2 /模式/ sharedBooking_v41_0"

如果我手动将 ns2 命名空间添加到该元素( AddAirPnrElement )并在SoapUI中发送相同的XML请求,一切正常。 所以问题是Soap Client没有为该属性设置名称空间。

这是WSDL:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SharedBookingService"
         xmlns="http://schemas.xmlsoap.org/wsdl/"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
         xmlns:tns="http://www.travelport.com/service/sharedBooking_v41_0"
         xmlns:ns1="http://www.travelport.com/schema/sharedBooking_v41_0"
   xmlns:sc="http://www.travelport.com/soa/common/security/SessionContext_v1"           targetNamespace="http://www.travelport.com/service/sharedBooking_v41_0">

   <import namespace="http://www.travelport.com/service/sharedBooking_v41_0" location="SharedBookingAbstract.wsdl"/>

   <binding name="BookingAirPnrElementBinding" type="tns:BookingAirPnrElementPortType">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="service">
        <soap:operation soapAction="https://americas.universal-api.travelport.com/B2BGateway/connect/uAPI/SharedBookingService"/>
        <input>
            <soap:header use="literal" part="sessionContext" message="tns:SessionContext"/>
            <soap:body use="literal"/>
        </input>
        <output>
            <soap:body use="literal"/>
        </output>
        <fault name="ErrorInfoMsg">
            <soap:fault name="ErrorInfoMsg" use="literal"/>
        </fault>
     </operation>
  </binding>

  <service name="SharedBookingService">
    <port name="BookingAirPnrElementPort" binding="tns:BookingAirPnrElementBinding">
        <soap:address location="https://americas.universal-api.travelport.com/B2BGateway/connect/uAPI/SharedBookingService"/>
    </port>
  </service>
</definitions>

任何人都可以帮助我理解为什么Soap Client没有设置名称空间吗?

非常感谢。

1 个答案:

答案 0 :(得分:1)

在仔细分析导入WSDL的XSD文件之后,我注意到架构属性中缺少 elementFormDefault =“qualified”。我将它添加到架构

<xs:schema xmlns="http://www.travelport.com/schema/sharedBooking_v41_0"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:common="http://www.travelport.com/schema/common_v41_0"
       xmlns:air="http://www.travelport.com/schema/air_v41_0"
       xmlns:hotel="http://www.travelport.com/schema/hotel_v41_0"
       targetNamespace="http://www.travelport.com/schema/sharedBooking_v41_0"
       elementFormDefault="qualified"

并且所有命名空间都出现在XML请求中。