0

Delphi xe3 の wsdl インポーターは、特定の wsdl / xsd に対して間違ったコードを生成しているようです。Web サービス自体は私たちが作成したものではありませんが、それを使用する必要があります。問題を説明するために、提供された xsd スキーマから関連する部分を取り除きました。

ここに問題を引き起こすと思われるXSDの一部があります

    <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>

Delphi が生成したコードの一部を次に示します。

  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;

XSD を見ると、デマンド タイプは他のすべてのデマンド タイプの基本クラスのように見え、人の配列しか含まれていないため、デマンドから派生したすべてのクラス (GarnishmentDemand など) には人の配列が必要です。問題は、delphi が Demand 型自体を person の配列として宣言したことです。それはクラスであるべきだったと思うので、GarnishmentDemand を作成すると person 配列にアクセスできません。

これは wsdl インポーターのバグですか、それとも wsdl/xsd に問題があるのでしょうか? もしそれがバグなら、どうにかして修正できますか?完了を押す前に、de wsdl importer ツールで多数のオプションを変更しようとしましたが、Demand タイプは常にクラスではなく人の配列として宣言されていました。

バグでない場合、GarnishmentDemand タイプを使用するときに、persons 配列にアクセスする方法がわかりませんか?

4

1 に答える 1

0

この問題の回避策を見つけました。

次のような Demand タイプの xsd にダミー要素を追加しました。

<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>

次に、wsdl/xsd を Delphi XE3 に再度インポートし、生​​成されたコードからダミー要素を削除しました。Delphi は Demand 型をクラスとして定義するようになり、他のすべての要求 (GarnishmentDemand など) は Demand クラスから継承され、最初に意図したように person 配列にアクセスできるようになりました

  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;

Delphi XE4 に同じバグが含まれているかどうかをテストします。含まれている場合は、embarcadero QA にレポートを提出できるかどうかを確認します。

于 2013-06-07T08:34:08.557 に答える