utiliza - Asistente de enlace de datos XML y uso de múltiples espacios de nombres
qué es un namespace y para qué se utiliza (0)
Estoy tratando de utilizar el asistente de enlace de datos XML en Delphi Seattle para generar interfaces para un conjunto determinado de archivos XSD. Sé que hay problemas con el uso de múltiples espacios de nombres en el asistente de XML, pero no puedo entender el problema / solución exacta ...
Antes de proporcionarle los detalles, mi pregunta es: ¿Cómo alterar el código generado para que interprete los prefijos del espacio de nombres que son diferentes en el XML resultante como lo están en la definición XSD?
Los XSD a partir de los cuales se genera el código son los siguientes
<?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>
Este XSD hace referencia al espacio de nombres de las estructuras de datos con los siguientes contenidos:
<?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>
Nota: Este XSD hace referencia a otros XSD como basetypes
y simpletypes
pero estos no se usan en el elemento ApplicationregistrationType, que es el problema aquí.
El código generado se ve así (solo se muestran las partes relevantes)
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.
El servicio REST me proporciona el siguiente XML de respuesta:
<?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>
Cuando creo una instancia con GetApplicationInstanceRegistrationResponse(XML)
tratando de obtener el valor de Key o Secret da un error OLEVariant, porque la ChildNodes[''key'']
en TXMLAppInstanceRegistrationType_rmrds.Get_Key
no puede encontrar el nodo. Cuando uso ChildNodes[''ns5:key'']
funciona pero el ns5
no es un prefijo de espacio de nombres fijo.
Ya he aceptado que el código generado por el asistente debe modificarse manualmente, ya que una búsqueda exhaustiva en la red no me proporcionó ninguna solución estructural para corregir los resultados del asistente.
Entonces, ¿cómo puedo solucionar esto y hacer que el TXMLAppInstanceRegistrationType_rmrds
sepa que sus elementos están definidos en el esquema de la datastructure
de datos?