WebService(Soap)与Delphi XE2的复杂响应

时间:2017-04-10 13:07:05

标签: delphi soap

我正在尝试使用Delphi创建一个WebService,简单的部分就是一个简单的响应。

但我的问题是如何使其成为多阵列/多级响应

例如:

我想得到这样的东西:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:RoommatikIntf-IRoommatik">
      <NS1:GetAllRoomTypeRatesResponse xmlns:NS2="urn:RoommatikIntf">
         <NS2:RoomTypeRate id="1" xsi:type="NS2:RoomTypeRate">
            <NS2:RoomType id="2" xsi:type="NS2:RoomType">
               <Id xsi:type="xsd:int">1</Id>
               <Name xsi:type="xsd:string">Test0</Name>
            </NS2:RoomType>
            <Price xsi:type="xsd:double">100.2</Price>
         </NS2:RoomTypeRate>
      </NS1:GetAllRoomTypeRatesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

RoomType位于RoomTypeRate标记内。

但目前我得到的只是字面意思:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:RoommatikIntf-IRoommatik">
      <NS1:GetAllRoomTypeRatesResponse xmlns:NS2="urn:RoommatikIntf">
         <return xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS2:RoomTypeRate[1]">
            <item href="#1"/>
         </return>
         <NS2:RoomTypeRate id="1" xsi:type="NS2:RoomTypeRate">
            <RoomType href="#2"/>
            <Price xsi:type="xsd:double">100.2</Price>
         </NS2:RoomTypeRate>
         <NS2:RoomType id="2" xsi:type="NS2:RoomType">
            <Id xsi:type="xsd:int">1</Id>
            <Name xsi:type="xsd:string">Test0</Name>
         </NS2:RoomType>
      </NS1:GetAllRoomTypeRatesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Intf文件是:

unit RoommatikIntf;

interface

uses Soap.InvokeRegistry, System.Types, Soap.XSBuiltIns;

const
  IS_OPTN = $0001;
  IS_UNBD = $0002;
  IS_NLBL = $0004;
  IS_REF  = $0080;

type

  RoomType = class(TRemotable)
  private
    FId: Integer;
    FName_: string;
  published
    property Id:          Integer  read FId write FId;
    property Name:        string   read FName_ write FName_;
  end;
  RoomTypeRate2 = class(TRemotable)
  private
    FRoomType : String;
  published
    property RoomType: String Read FRoomType write FRoomType;
  end;

  RoomTypeRate = class(TRemotable)
  private
    FRoomType: RoomType;
    FPrice: Double;
  published
    property RoomType:     RoomType      Index (IS_OPTN) read FRoomType write FRoomType;
    property Price:        Double        read FPrice write FPrice;
  end;

  ArrayOfRoomTypeRate = array of RoomTypeRate;

  { Invokable interfaces must derive from IInvokable }
  IRoommatik = interface(IInvokable)
  ['{DB8CC9DF-B105-4CCF-9CE5-C45EBCF4CF43}']

    { Methods of Invokable interface must not use the default }
    { calling convention; stdcall is recommended }
    function GetDateTime: TXSDateTime; stdcall;
    function GetAllRoomTypeRates: ArrayOfRoomTypeRate; stdcall;
  end;

implementation

initialization
  { Invokable interfaces must be registered }
  InvRegistry.RegisterInterface(TypeInfo(IRoommatik));


end.

和Impl文件是:

unit RoommatikImpl;

interface

uses Soap.InvokeRegistry, System.Types, Soap.XSBuiltIns, RoommatikIntf, DateUtils, SysUtils;

type

  { TRoommatik }
  TRoommatik = class(TInvokableClass, IRoommatik)
  public
    function GetAllRoomTypeRates: ArrayOfRoomTypeRate; stdcall;
    function GetDateTime: TXSDateTime; stdcall;
  end;

implementation

function TRoommatik.GetDateTime: TXSDateTime; stdcall;
var
  DateTime : TXSDateTime;
begin
  DateTime := TXSDateTime.Create;
  DateTime.AsDateTime := now+1;
  Result := DateTime;
end;

function TRoommatik.GetAllRoomTypeRates: ArrayOfRoomTypeRate; stdcall;
Var
  RoomArray : ArrayOfRoomTypeRate;
begin
  RoomArray := ArrayOfRoomTypeRate.Create();
  SetLength(RoomArray, 1);
  RoomArray[0] := RoomTypeRate.Create;
  RoomArray[0].RoomType := RoomType.Create;
  RoomArray[0].RoomType.Id := 1;
  RoomArray[0].RoomType.Name := 'Test0';
  RoomArray[0].Price    := 100.20;

  Result := RoomArray;
end;



initialization
{ Invokable classes must be registered }
   InvRegistry.RegisterInvokableClass(TRoommatik);
end.

请指出正确的方向,因为我找不到有关如何正确使用此信息的信息。

谢谢你。

0 个答案:

没有答案