You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi XE10调用DHL API时WSDL生成嵌套数组对象初始化问题

Delphi WSDL导入生成多层级复杂类型的标准使用方法

核心问题原因

Delphi自带的WSDL导入工具生成的SOAP请求类中,所有嵌套的复杂类型属性、数组类型属性默认均为未初始化的nil状态,运行时不会自动创建子对象实例,这是官方设计的标准行为,逐层手动实例化才是符合Delphi SOAP开发规范的实现方式。

多层级结构访问示例

以下为你提到的<Items><Item><Product>层级结构的完整使用示例,首先是WSDL导入后自动生成的典型类型定义:

type
  // 对应<Product>节点
  ProductType = class(TRemotable)
  private
    FProductCode: string;
    FProductName: string;
  published
    property ProductCode: string read FProductCode write FProductCode;
    property ProductName: string read FProductName write FProductName;
  end;

  // 对应<Item>节点
  ItemType = class(TRemotable)
  private
    FProduct: ProductType;
    FItemId: string;
  published
    property ItemId: string read FItemId write FItemId;
    property Product: ProductType read FProduct write FProduct;
  end;

  // 对应<Items>下的Item数组
  Array_Of_Item = array of ItemType;

  // 对应根节点<Items>
  ItemsType = class(TRemotable)
  private
    FItem: Array_Of_Item;
  published
    property Item: Array_Of_Item read FItem write FItem;
  end;

正确的初始化、访问、赋值代码如下:

var
  Items: ItemsType;
begin
  // 1. 初始化根节点对象
  Items := ItemsType.Create;
  try
    // 2. 为Item数组分配1个元素长度
    SetLength(Items.Item, 1);
    // 3. 初始化数组内的Item对象
    Items.Item[0] := ItemType.Create;
    // 4. 初始化Item下的Product子对象
    Items.Item[0].Product := ProductType.Create;

    // 此时可正常访问深层属性
    Items.Item[0].ItemId := 'ITEM001';
    Items.Item[0].Product.ProductCode := 'P001';
    Items.Item[0].Product.ProductName := '测试商品';
    ShowMessage(Items.Item[0].Product.ProductName);
  finally
    // 注意:若将对象若直接传入SOAP接口方法时不需要手动释放,SOAP运行时会在请求完成后自动释放关联对象,手动释放会引发重复释放错误
  end;
end;

DHL ShipmentOrder场景修复代码

对应你的测试场景,修正后的可正常访问代码如下,注意子对象类名需要和你WSDL导入生成的单元内实际类名保持一致:

var
  IShipmentorder : Array_Of_ShipmentOrderType;
Begin
  SetLength(IShipmentorder,1); 
  IShipmentorder[0] := shipmentordertype.Create;
  // 手动初始化Shipment子对象
  IShipmentorder[0].Shipment := ShipmentType.Create;
  // 手动初始化Shipment下的Shipmentdetails子对象
  IShipmentorder[0].Shipment.Shipmentdetails := ShipmentDetailsType.Create;

  // 此时可正常访问所有层级属性
  ShowMessage(IShipmentorder[0].UnitName);
  ShowMessage(IShipmentorder[0].Shipment.UnitName);
  ShowMessage(IShipmentorder[0].Shipment.Shipmentdetails.UnitName);
End;

可选优化方案

如果嵌套层级过多,可自行封装通用递归初始化函数即可简化开发:通过RTTI遍历类的所有published属性,若属性为TRemotable子类且为nil则自动创建实例,数组类型可按需求分配默认长度,实现时注意跳过存在循环引用的属性即可。

内容的提问来源于stack exchange,提问作者Radi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 01:45:01