是否可以使用Delphi发送和接收XML到WSDL函数..?

时间:2014-08-06 16:58:29

标签: web-services delphi soap wsdl delphi-2010

我们过去曾使用过Delphi的Web Services,而且参数很少,并且只向客户端返回一个值。我们工作的新服务应该能够输入XML并接收XML输出。

是否有可用于此目的的组件?

当我尝试使用如下所示时收到错误“SearchAgreements输入参数XmlElement中的异常 - System.NullReferenceException:对象引用未设置为对象的实例。”

  LDocument := NewXMLDocument;
  <<framed an XML input>>
  DocSearchOut := SearchArgsResponse.Create();
  DoxSerchIn := SearchArgs.Create();
  DoxSerchIn.SOAPTOObject(LDocument.DocumentElement,LDocument.DocumentElement,HTTPRIO1.Converter);
  DoxService := GetIDoxService(True,'',HTTPRIO1);
  DocSearchOut :=DoxService.SearchAgreements(DoxSerchIn)

我甚至尝试将SearchArgs转换为宽字符串,并尝试将其作为字符串传递。这对HTTPRIO执行稍作修改。最终修改

  LDocument := NewXMLDocument;
  <<framed an XML input>>
  DocSearchOut := SearchArgsResponse.Create();
  DoxSerchIn := SearchArgs.Create();
  DoxSerchIn.SearchArgs := LDocument.DocumentElement.XML;
  DoxService := GetIDoxService(True,'',HTTPRIO1);
  DocSearchOut :=DoxService.SearchAgreements(DoxSerchIn)

其wsdl

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:i0="http://www.bank.com/dox/service/v1.0.0" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="DoxService" targetNamespace="http://tempuri.org/">
<wsdl:import namespace="http://www.bank.com/dox/service/v1.0.0" location="http://devldn.ldn.bank.com:8258/doxManual/DoxService.svc?wsdl=wsdl0"/>
<wsdl:types/>
<wsdl:binding name="BasicHttpBinding_IDoxService" type="i0:IDoxService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="SearchAgreements">
<soap:operation soapAction="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreements" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DoxService">
<wsdl:port name="BasicHttpBinding_IDoxService" binding="tns:BasicHttpBinding_IDoxService">
<soap:address location="http://devldn.ldn.bank.com:8258/doxManual/DoxService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

wsdl0

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://www.bank.com/dox/service/v1.0.0" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" targetNamespace="http://www.bank.com/dox/service/v1.0.0">
<wsdl:types>
<xsd:schema targetNamespace="http://www.bank.com/dox/service/v1.0.0/Imports">
<xsd:import schemaLocation="http://ldndev.ldn.bank.com:8258/doxManual/DoxService.svc?xsd=xsd0" namespace="http://www.bank.com/dox/service/v1.0.0"/>
<xsd:import schemaLocation="http://ldndev.ldn.bank.com:8258/doxManual/DoxService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IDoxService_SearchAgreements_InputMessage">
<wsdl:part name="parameters" element="tns:SearchAgreements"/>
</wsdl:message>
<wsdl:message name="IDoxService_SearchAgreements_OutputMessage">
<wsdl:part name="parameters" element="tns:SearchAgreementsResponse"/>
</wsdl:message>
<wsdl:portType name="IDoxService">
<wsdl:operation name="SearchAgreements">
<wsdl:input wsaw:Action="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreements" message="tns:IDoxService_SearchAgreements_InputMessage"/>
<wsdl:output wsaw:Action="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreementsResponse" message="tns:IDoxService_SearchAgreements_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>

xsd0

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.bank.com/dox/service/v1.0.0" elementFormDefault="qualified" targetNamespace="http://www.bank.com/dox/service/v1.0.0">
<xs:element name="SearchAgreements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="searchRequest" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SearchAgreementsResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="SearchAgreementsResult" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

xsd1

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
<xs:element name="anyType" nillable="true" type="xs:anyType"/>
<xs:element name="anyURI" nillable="true" type="xs:anyURI"/>
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary"/>
<xs:element name="boolean" nillable="true" type="xs:boolean"/>
<xs:element name="byte" nillable="true" type="xs:byte"/>
<xs:element name="dateTime" nillable="true" type="xs:dateTime"/>
<xs:element name="decimal" nillable="true" type="xs:decimal"/>
<xs:element name="double" nillable="true" type="xs:double"/>
<xs:element name="float" nillable="true" type="xs:float"/>
<xs:element name="int" nillable="true" type="xs:int"/>
<xs:element name="long" nillable="true" type="xs:long"/>
<xs:element name="QName" nillable="true" type="xs:QName"/>
<xs:element name="short" nillable="true" type="xs:short"/>
<xs:element name="string" nillable="true" type="xs:string"/>
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte"/>
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt"/>
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong"/>
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort"/>
<xs:element name="char" nillable="true" type="tns:char"/>
<xs:simpleType name="char">
<xs:restriction base="xs:int"/>
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration"/>
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?"/>
<xs:minInclusive value="-P10675199DT2H48M5.4775808S"/>
<xs:maxInclusive value="P10675199DT2H48M5.4775807S"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid"/>
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/>
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName"/>
<xs:attribute name="Id" type="xs:ID"/>
<xs:attribute name="Ref" type="xs:IDREF"/>
</xs:schema>

输入服务..不幸的是,团队添加了一些东西,因此无法在SOAP UI上检索输出。

   <AgreementSearchRequest xmlns="http://www.bank.com/dox/service/v1.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Header>
    <PageNo>1</PageNo>
    <PageSize>10</PageSize>
    <Source>IBFD</Source>
  </Header>
  <SearchCriteria>
    <AgreementId>10</AgreementId>
    <AgreementStatus>Search Status</AgreementStatus>
    <AgreementType>Search Type</AgreementType>
    <AgreementVersion>Search Version</AgreementVersion>
    <CompletedDate>2014-05-30T15:56:45.7533005+05:30</CompletedDate>
    <ContractingEntity>Search GCRS Code</ContractingEntity>
    <CounterpartyBranch>Search CP Branch</CounterpartyBranch>
    <CounterpartyEMID>Search CP EMID</CounterpartyEMID>
    <CounterpartyId>Search CP ID</CounterpartyId>
    <CounterpartyName>Search CP Name</CounterpartyName>
    <CounterpartyType>Search CP Type</CounterpartyType>
    <CreditContact>Search Contact</CreditContact>

    <IsOffshoreUser>true</IsOffshoreUser>
    <Products>
      <Product>
        <ProductCode>Search Code</ProductCode>:=
        <ProductName i:nil="true"/>
      </Product>
    </Products>
    <RXM>Search RXM</RXM>
    <RequestedDate>2014-05-30T15:56:45.758183+05:30</RequestedDate>
    <bankLegalEntity>Search LEgal Entity</bankLegalEntity>
    <bankLegalEntityCategory>Search Legal Entity Category</bankLegalEntityCategory>
    <UmbrellaCounterpartyEMID>Search Agent EMID</UmbrellaCounterpartyEMID>
    <UmbrellaCounterpartyName>Search Agent Name</UmbrellaCounterpartyName>
  </SearchCriteria>

我尝试导入xsd并替换xml文件HTTPRIO在执行前提到here..

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.bank.com/dox/service/v1.0.0" elementFormDefault="qualified" targetNamespace="http://www.bank.com/dox/service/v1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="ArrayOfProduct">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Product" nillable="true" type="tns:Product" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfProduct" nillable="true" type="tns:ArrayOfProduct" />
  <xs:complexType name="Product">
    <xs:sequence>
      <xs:element minOccurs="0" name="ProductCode" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="ProductName" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Product" nillable="true" type="tns:Product" />
    <xs:complexType name="AgreementSearchRequest">
    <xs:sequence>
      <xs:element name="Header" nillable="true" type="tns:AgreementSearchRequestHeader" />
      <xs:element name="SearchCriteria" nillable="true" type="tns:AgreementSearchCriteria" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="AgreementSearchRequest" nillable="true" type="tns:AgreementSearchRequest" />
  <xs:complexType name="AgreementSearchRequestHeader">
    <xs:sequence>
      <xs:element name="PageNo" type="xs:int" />
      <xs:element name="PageSize" type="xs:int" />
      <xs:element name="Source" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="AgreementSearchRequestHeader" nillable="true" type="tns:AgreementSearchRequestHeader" />
  <xs:complexType name="AgreementSearchCriteria">
    <xs:sequence>
      <xs:element minOccurs="0" name="AgreementId" type="xs:int" />
      <xs:element minOccurs="0" name="AgreementStatus" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="AgreementType" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="AgreementVersion" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CompletedDate" type="xs:dateTime" />
      <xs:element minOccurs="0" name="ContractingEntity" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CounterpartyBranch" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CounterpartyEMID" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CounterpartyId" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CounterpartyName" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CounterpartyType" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="CreditContact" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="Products" nillable="true" type="tns:ArrayOfProduct" />
      <xs:element minOccurs="0" name="RXM" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="RequestedDate" type="xs:dateTime" />
      <xs:element minOccurs="0" name="egalEntity" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="LegalEntityCategory" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="UmbrellaCounterpartyEMID" nillable="true" type="xs:string" />
      <xs:element minOccurs="0" name="UmbrellaCounterpartyName" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="AgreementSearchCriteria" nillable="true" type="tns:AgreementSearchCriteria" />
</xs:schema>

2 个答案:

答案 0 :(得分:2)

Web Service Toolkit

它有一个代码生成器,它接受wsdl并从中生成与Web服务交互的Pascal类。

似乎正是你所需要的,但我不知道具体细节。


然后我的Internet Tools也是FreePascal(不是Delphi)。

它们包含XQuery的解释器,XQuery是一种通用的XML处理语言,因此您可以将它与每个可能的基于XML / HTML的API一起使用,其代码远远少于使用DOM方法。但它无法帮助您解决任何特定于WSDL的问题,您需要自己为每个请求编写XML。

答案 1 :(得分:1)

根据vaiours论坛上的其他观点(包括堆栈溢出),我们通过在2个地方修复来解决问题。

更改了Delphi生成的远程过程。早期它是一类输入参数本身,所以我们改为WideString

  SearchAgreements = class(TRemotable)
  private
    FsearchRequest: WideString ; 
    FsearchRequest_Specified: boolean;
    procedure SetsearchRequest(Index: Integer; const AsearchRequest: WideString ); 
    function  searchRequest_Specified(Index: Integer): boolean;
  public
    destructor Destroy; override;
  published                
    property searchRequest: WideString   Index (IS_OPTN) read FsearchRequest write SetsearchRequest stored searchRequest_Specified;
  end;

我们还修改了HTTPRIO在执行之前进行了少量修改,我们能够成功地将XML发送给服务。

procedure HTTPRIO1SoapBeforeExecute(const MethodName: string;
  SOAPRequest: TStream);
var
 StrTemp,Fheader : TStringList;
  StrBeg,StrEnd,StrParam,StrParam1  : TStringList;
  StreamTemp : TStream;
  StrLst : TStringList;
  StrLstTmp: TStringList;

begin
  StrBeg:=TStringList.Create();
  StrEnd:=TStringList.Create();
  SOAPRequest.Position := 0;
  StrTemp.LoadFromStream(SOAPRequest);
  StrBeg.Text := StringReplace(StrTemp.Text,'&lt;','<',[RfReplaceAll]);
  StrEnd.Text := StringReplace(StrBeg.Text,'&gt;','>',[RfReplaceAll]);
  SOAPRequest.Position:=0;
  SOAPRequest.Size := 0; //Clear the Stream
  StrEnd.SaveToStream(SOAPRequest); //Reinitialise the stream with right string.
  SOAPRequest.Position :=0;
end;

我们已经在Webservices上调用了PHd,因此任何面临类似问题的人都可以联系我。谢谢:)