XML 数据绑定向导和使用多个命名空间

XML Data binding wizard and using multiple namespaces

提问人:Bascy 提问时间:3/31/2016 更新时间:1/2/2018 访问量:1258

问:

我正在尝试使用 Delphi Seattle 中的 XML 数据绑定向导为一组给定的 XSD 文件生成接口。我知道在XML向导中使用多个命名空间存在问题,但我无法让自己理解确切的问题/解决方案。

在为您提供大量详细信息之前,简而言之,我的问题是:如何更改生成的代码以使其解释在生成的 XML 中与 XSD 定义中不同的命名空间前缀?

生成代码的 XSD 如下所示

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="application/registration/2014/04" elementFormDefault="qualified"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:rmrds="datamodel/canonical/datastructures/2014/01/">

    <import schemaLocation="CanonicalDataModel/CanonicalDataModel_DataStructures.xsd" namespace="datamodel/canonical/datastructures/2014/01/">
    </import>

    <element name="ApplicationInstanceRegistrationResponse">
        <complexType>
            <sequence>
                <element name="registrationResponse" type="rmrds:AppInstanceRegistrationType" />
            </sequence>
        </complexType>
    </element>
</schema>

此 XSD 引用具有以下内容的 datastructures 命名空间:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="datamodel/canonical/datastructures/2014/01/"
    xmlns:rmrds="datamodel/canonical/datastructures/2014/01/" elementFormDefault="qualified"
    xmlns:rmrbt="datamodel/canonical/basetypes/2014/01/" xmlns:rmrst="datamodel/canonical/simpletypes/2014/01/">

    <import schemaLocation="CanonicalDataModel_BaseTypes.xsd" namespace="datamodel/canonical/basetypes/2014/01/" />
    <import schemaLocation="CanonicalDataModel_SimpleTypes.xsd" namespace="datamodel/canonical/simpletypes/2014/01/" />

    <complexType name="AppInstanceRegistrationType">
        <sequence>
            <element name="key" type="string" />
            <element name="secret" type="string" />
        </sequence>
    </complexType>
</schema>

注意:此 XSD 引用了其他 XSD,例如 和 ,但这些 XSD 未在此处问题的 ApplicationregistrationType 元素中使用basetypessimpletypes

生成的代码如下所示(仅显示相关部分)

type

  IXMLApplicationInstanceRegistrationResponse = interface;
  IXMLAppInstanceRegistrationType_rmrds = interface;

  IXMLApplicationInstanceRegistrationResponse = interface(IXMLNode)
    ['{045B5E7C-83E2-4DB3-B7CD-7C2C28E0E387}']
    { Property Accessors }
    function Get_RegistrationResponse: IXMLAppInstanceRegistrationType_rmrds;
    { Methods & Properties }
    property RegistrationResponse: IXMLAppInstanceRegistrationType_rmrds read Get_RegistrationResponse;
  end;

  IXMLAppInstanceRegistrationType_rmrds = interface(IXMLNode)
    ['{2C1869A9-8B9E-4EC1-9320-5F6683BCB20E}']
    { Property Accessors }
    function Get_Key: String;
    function Get_Secret: String;
    procedure Set_Key(Value: String);
    procedure Set_Secret(Value: String);
    { Methods & Properties }
    property Key: String read Get_Key write Set_Key;
    property Secret: String read Get_Secret write Set_Secret;
  end;

  TXMLApplicationInstanceRegistrationResponse = class;
  TXMLAppInstanceRegistrationType_rmrds = class;

  TXMLApplicationInstanceRegistrationResponse = class(TXMLNode, IXMLApplicationInstanceRegistrationResponse)
  protected
    { IXMLApplicationInstanceRegistrationResponse }
    function Get_RegistrationResponse: IXMLAppInstanceRegistrationType_rmrds;
  public
    procedure AfterConstruction; override;
  end;

{ TXMLAppInstanceRegistrationType_rmrds }

  TXMLAppInstanceRegistrationType_rmrds = class(TXMLNode, IXMLAppInstanceRegistrationType_rmrds)
  protected
    { IXMLAppInstanceRegistrationType_rmrds }
    function Get_Key: String;
    function Get_Secret: String;
    procedure Set_Key(Value: String);
    procedure Set_Secret(Value: String);
  end;

{ Global Functions }

function GetApplicationInstanceRegistrationResponse(Doc: IXMLDocument): IXMLApplicationInstanceRegistrationResponse;
function LoadApplicationInstanceRegistrationResponse(const FileName: string): IXMLApplicationInstanceRegistrationResponse;
function NewApplicationInstanceRegistrationResponse: IXMLApplicationInstanceRegistrationResponse;

const
  TargetNamespace = 'application/registration/2014/04';

implementation

{ Global Functions }

function GetApplicationInstanceRegistrationResponse(Doc: IXMLDocument): IXMLApplicationInstanceRegistrationResponse;
begin
  Result := Doc.GetDocBinding('ApplicationInstanceRegistrationResponse', TXMLApplicationInstanceRegistrationResponse, TargetNamespace) as IXMLApplicationInstanceRegistrationResponse;
end;

function LoadApplicationInstanceRegistrationResponse(const FileName: string): IXMLApplicationInstanceRegistrationResponse;
begin
  Result := LoadXMLDocument(FileName).GetDocBinding('ApplicationInstanceRegistrationResponse', TXMLApplicationInstanceRegistrationResponse, TargetNamespace) as IXMLApplicationInstanceRegistrationResponse;
end;

function NewApplicationInstanceRegistrationResponse: IXMLApplicationInstanceRegistrationResponse;
begin
  Result := NewXMLDocument.GetDocBinding('ApplicationInstanceRegistrationResponse', TXMLApplicationInstanceRegistrationResponse, TargetNamespace) as IXMLApplicationInstanceRegistrationResponse;
end;

{ TXMLApplicationInstanceRegistrationResponse }

procedure TXMLApplicationInstanceRegistrationResponse.AfterConstruction;
begin
  RegisterChildNode('registrationResponse', TXMLAppInstanceRegistrationType_rmrds);
  inherited;
end;

function TXMLApplicationInstanceRegistrationResponse.Get_RegistrationResponse: IXMLAppInstanceRegistrationType_rmrds;
begin
  Result := ChildNodes['registrationResponse'] as IXMLAppInstanceRegistrationType_rmrds;
end;

{ TXMLAppInstanceRegistrationType_rmrds }

function TXMLAppInstanceRegistrationType_rmrds.Get_Key: String;
begin
  Result := ChildNodes['key'].NodeValue;
end;

procedure TXMLAppInstanceRegistrationType_rmrds.Set_Key(Value: String);
begin
  ChildNodes['key'].NodeValue := Value;
end;

function TXMLAppInstanceRegistrationType_rmrds.Get_Secret: String;
begin
  Result := ChildNodes['secret'].NodeValue;
end;

procedure TXMLAppInstanceRegistrationType_rmrds.Set_Secret(Value: String);
begin
  ChildNodes['secret'].NodeValue := Value;
end;
end.

REST服务为我提供了以下答案XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns10:ApplicationInstanceRegistrationResponse 
   xmlns="datamodel/financial/modelobjects/2014/01/"
   xmlns:ns3="canonical/basetypes/2014/01/"
   xmlns:ns5="datamodel/canonical/datastructures/2014/01/"
   xmlns:ns6="datamodel/canonical/simpletypes/2014/01/" 
   xmlns:ns10="application/registration/2014/04" 

  <ns10:registrationResponse>
    <ns5:key>cac7bacc</ns5:key>
    <ns5:secret>NzY2MDkwNzliNjJkZTE1MWRjNGViNTI4MTk4MmZjZDkzYzhmY2UwNDA5YmJhMjlhYzVlY2JjZGFmNWE1NDg2OA==</ns5:secret>
  </ns10:registrationResponse>
</ns10:ApplicationInstanceRegistrationResponse>

当我尝试获取 Key 或 Secret 的值创建实例时,会出现 OLEVariant 错误,因为 中的语句找不到节点。当我使用它时,它可以工作,但不是固定的命名空间前缀。GetApplicationInstanceRegistrationResponse(XML)ChildNodes['key']TXMLAppInstanceRegistrationType_rmrds.Get_KeyChildNodes['ns5:key']ns5

我已经接受了向导生成的代码必须手动更改,因为网络上的广泛搜索并没有为我提供任何修复向导结果的结构解决方案。

那么,我该如何解决这个问题并意识到其元素已在架构中定义呢?TXMLAppInstanceRegistrationType_rmrdsdatastructure

xml delphi xsd xml 解析

评论


答: 暂无答案