i think the wsdl importer from delphi xe3 seems to generate wrong code for a certain wsdl / xsd. The webservice itself is not made by us, but we need to consume it. I stripped out the relevant parts from the xsd schema we got supplied to illustrate the problem.
here's part of the XSD that i think causes problems
<xs:element name="request">
<xs:complexType>
<xs:sequence>
<xs:element type="Demand" name="demand" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Demand" abstract="true">
<xs:sequence>
<xs:element name="person" type="Person" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Person" abstract="true">
<xs:sequence>
<xs:element name="name" minOccurs="0" maxOccurs="1">
</xs:sequence>
<xs:attribute name="key" type="xs:ID" use="required" />
</xs:complexType>
<xs:complexType name="MoralPerson">
<xs:complexContent>
<xs:extension base="Person">
<xs:sequence>
<xs:element name="juridicalForm">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:maxInclusive value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="GarnishmentDemand">
<xs:complexContent>
<xs:extension base="Demand">
<xs:sequence>
<xs:element name="saleTotalAmount" type="Amount" minOccurs="1" maxOccurs="1" />
<xs:element name="saleDate" type="xs:date" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
here's some of the code delphi generated
Person = class(TRemotable)
private
Fkey: string;
Fname_: name_;
Fname__Specified: boolean;
procedure Setname_(Index: Integer; const Aname_: name_);
function name__Specified(Index: Integer): boolean;
published
property key: string Index (IS_ATTR) read Fkey write Fkey;
property name_: name_ Index (IS_OPTN) read Fname_ write Setname_ stored name__Specified;
end;
MoralPerson = class(Person)
private
FjuridicalForm: juridicalForm;
published
property juridicalForm: juridicalForm read FjuridicalForm write FjuridicalForm;
end;
Demand = array of Person;
CreateNoticeOneRequest = class(TRemotable)
private
Fdossier: Dossier;
Fdemand: Demand;
public
destructor Destroy; override;
published
property demand: Demand read Fdemand write Fdemand;
end;
GarnishmentDemand = class(TRemotable)
private
FsaleTotalAmount: Amount;
FsaleDate: TXSDate;
public
destructor Destroy; override;
published
property saleTotalAmount: Amount read FsaleTotalAmount write FsaleTotalAmount;
property saleDate: TXSDate read FsaleDate write FsaleDate;
end;
when i look at the XSD the demand type seems to be the base class for all other demand types and only contains an array of persons, so all derived classes from demand (like GarnishmentDemand) should have an array of persons. The problem is that delphi declared the Demand type itself as an array of person and i think it should have been a class, so when i create a GarnishmentDemand i'm unable to access the person array.
Is this a bug in the wsdl importer, am i seeing it all wrong or are the wsdl/xsd supplied faulty ? if it is a bug can it somehow be corrected? I tried changing numerous options in de wsdl importer tool before pressing finish but the Demand type was always declared as an array of person instead of a class.
If it isn't a bug then i don't see how i should be able to access the persons array when using the GarnishmentDemand type?
i found a workaround solution for this problem.
i added a dummy element in the xsd for the Demand type like this:
<xs:complexType name="Demand" abstract="true">
<xs:sequence>
<xs:element name="person" type="Person" minOccurs="1" maxOccurs="unbounded" />
<xs:element name="dummy" type="xs:boolean" minOccurs="0" maxOccurs="1" nillable="true"/>
</xs:sequence>
</xs:complexType>
then i imported the wsdl/xsd again in delphi XE3 and removed the dummy element from the generated code. Delphi now defines the Demand type as a class and all other demands (like the GarnishmentDemand) inherit from the Demand class and i'm able to access the person array like it was intended in the first place
Demand = class(TRemotable)
private
Fperson: Array_Of_Person;
Fdummy: Boolean;
Fdummy_Specified: boolean;
procedure Setdummy(Index: Integer; const ABoolean: Boolean);
function dummy_Specified(Index: Integer): boolean;
public
destructor Destroy; override;
published
property person: Array_Of_Person Index (IS_UNBD) read Fperson write Fperson;
property dummy: Boolean Index (IS_OPTN or IS_NLBL) read Fdummy write Setdummy stored dummy_Specified;
end;
GarnishmentDemand = class(Demand)
private
FsaleTotalAmount: Amount;
FsaleDate: TXSDate;
public
destructor Destroy; override;
published
property saleTotalAmount: Amount read FsaleTotalAmount write FsaleTotalAmount;
property saleDate: TXSDate read FsaleDate write FsaleDate;
end;
I'll test to see if delphi XE4 contains the same bug, if it does, i'll see if i can file a report with embarcaderro QA