El ejemplo que expondré se trata sobre obtener las propiedades que el usuario quiera configurar para obtenerlas de manera dinámica en tiempo de ejecución y asignarlas a las propiedades de su form, botones, lo que quieras.
================================Mi XML================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<reportesDinamicos>
<propiedadesReportes>
<reporte>
<nombre>CuentaTipo</nombre>
<caracteristicas>
<propiedades id="captionForm" value="Reporte 5"></propiedades>
<propiedades id="captionBotonAdelante" value="Origenes y aplicaciones"></propiedades>
<propiedades id="captionBotonAtras" value="Saldo integrado"></propiedades>
</caracteristicas>
</reporte>
<reporte>
<nombre>OrigenYAplicacion</nombre>
<caracteristicas>
<propiedades id="captionForm" value="Reporte 6"></propiedades>
<propiedades id="captionBotonAdelante" value=""></propiedades>
<propiedades id="captionBotonAtras" value="Cuentas tipo"></propiedades>
</caracteristicas>
</reporte>
</propiedadesReportes>
</reportesDinamicos>
================================Mi XML Data Binding================================
{************************************************************************************************}
{ }
{ XML Data Binding }
{ }
{ Generated on: 11/10/2011 03:54:27 p.m. }
{ Generated from: C:\Documents and Settings\DESARROLLO\Escritorio\propertiesReportes.xsd }
{ Settings stored in: C:\Documents and Settings\DESARROLLO\Escritorio\propertiesReportes.xdb }
{ }
{************************************************************************************************}
unit propertiesReportes;
interface
uses xmldom, XMLDoc, XMLIntf;
type
{ Forward Decls }
IXMLReportesDinamicos = interface;
IXMLListaImpuestos = interface;
IXMLImpuesto = interface;
IXMLPropiedadesReportes = interface;
IXMLReporte = interface;
IXMLCaracteristicas = interface;
IXMLPropiedades = interface;
{ IXMLReportesDinamicos }
IXMLReportesDinamicos = interface(IXMLNode)
['{3FD06A51-0CDB-4825-88BF-ADF843F1654D}']
{ Property Accessors }
function Get_ListaImpuestos: IXMLListaImpuestos;
function Get_PropiedadesReportes: IXMLPropiedadesReportes;
{ Methods & Properties }
property ListaImpuestos: IXMLListaImpuestos read Get_ListaImpuestos;
property PropiedadesReportes: IXMLPropiedadesReportes read Get_PropiedadesReportes;
end;
{ IXMLListaImpuestos }
IXMLListaImpuestos = interface(IXMLNodeCollection)
['{526DD339-C387-4626-ACC3-BFA19FA023FF}']
{ Property Accessors }
function Get_Impuesto(Index: Integer): IXMLImpuesto;
{ Methods & Properties }
function Add: IXMLImpuesto;
function Insert(const Index: Integer): IXMLImpuesto;
property Impuesto[Index: Integer]: IXMLImpuesto read Get_Impuesto; default;
end;
{ IXMLImpuesto }
IXMLImpuesto = interface(IXMLNode)
['{57355EF7-615E-4261-8ADB-01E4533CAFD1}']
{ Property Accessors }
function Get_Clave: WideString;
function Get_Descripcion: WideString;
procedure Set_Clave(Value: WideString);
procedure Set_Descripcion(Value: WideString);
{ Methods & Properties }
property Clave: WideString read Get_Clave write Set_Clave;
property Descripcion: WideString read Get_Descripcion write Set_Descripcion;
end;
{ IXMLPropiedadesReportes }
IXMLPropiedadesReportes = interface(IXMLNodeCollection)
['{415E435D-5042-4A90-A934-9D70EF05AE4C}']
{ Property Accessors }
function Get_Reporte(Index: Integer): IXMLReporte;
{ Methods & Properties }
function Add: IXMLReporte;
function Insert(const Index: Integer): IXMLReporte;
property Reporte[Index: Integer]: IXMLReporte read Get_Reporte; default;
end;
{ IXMLReporte }
IXMLReporte = interface(IXMLNode)
['{807AF82A-6A45-4DF6-A918-B8E1AE57A4FF}']
{ Property Accessors }
function Get_Nombre: WideString;
function Get_Caracteristicas: IXMLCaracteristicas;
procedure Set_Nombre(Value: WideString);
{ Methods & Properties }
property Nombre: WideString read Get_Nombre write Set_Nombre;
property Caracteristicas: IXMLCaracteristicas read Get_Caracteristicas;
end;
{ IXMLCaracteristicas }
IXMLCaracteristicas = interface(IXMLNodeCollection)
['{25F7BF5B-E4A9-4664-BBE4-4DD767694E88}']
{ Property Accessors }
function Get_Propiedades(Index: Integer): IXMLPropiedades;
{ Methods & Properties }
function Add: IXMLPropiedades;
function Insert(const Index: Integer): IXMLPropiedades;
property Propiedades[Index: Integer]: IXMLPropiedades read Get_Propiedades; default;
end;
{ IXMLPropiedades }
IXMLPropiedades = interface(IXMLNode)
['{BE9CFE34-AD62-4AB1-9DEC-B876D5F86872}']
{ Property Accessors }
function Get_Id: WideString;
function Get_Value: WideString;
procedure Set_Id(Value: WideString);
procedure Set_Value(Value: WideString);
{ Methods & Properties }
property Id: WideString read Get_Id write Set_Id;
property Value: WideString read Get_Value write Set_Value;
end;
{ Forward Decls }
TXMLReportesDinamicos = class;
TXMLListaImpuestos = class;
TXMLImpuesto = class;
TXMLPropiedadesReportes = class;
TXMLReporte = class;
TXMLCaracteristicas = class;
TXMLPropiedades = class;
{ TXMLReportesDinamicos }
TXMLReportesDinamicos = class(TXMLNode, IXMLReportesDinamicos)
protected
{ IXMLReportesDinamicos }
function Get_ListaImpuestos: IXMLListaImpuestos;
function Get_PropiedadesReportes: IXMLPropiedadesReportes;
public
procedure AfterConstruction; override;
end;
{ TXMLListaImpuestos }
TXMLListaImpuestos = class(TXMLNodeCollection, IXMLListaImpuestos)
protected
{ IXMLListaImpuestos }
function Get_Impuesto(Index: Integer): IXMLImpuesto;
function Add: IXMLImpuesto;
function Insert(const Index: Integer): IXMLImpuesto;
public
procedure AfterConstruction; override;
end;
{ TXMLImpuesto }
TXMLImpuesto = class(TXMLNode, IXMLImpuesto)
protected
{ IXMLImpuesto }
function Get_Clave: WideString;
function Get_Descripcion: WideString;
procedure Set_Clave(Value: WideString);
procedure Set_Descripcion(Value: WideString);
end;
{ TXMLPropiedadesReportes }
TXMLPropiedadesReportes = class(TXMLNodeCollection, IXMLPropiedadesReportes)
protected
{ IXMLPropiedadesReportes }
function Get_Reporte(Index: Integer): IXMLReporte;
function Add: IXMLReporte;
function Insert(const Index: Integer): IXMLReporte;
public
procedure AfterConstruction; override;
end;
{ TXMLReporte }
TXMLReporte = class(TXMLNode, IXMLReporte)
protected
{ IXMLReporte }
function Get_Nombre: WideString;
function Get_Caracteristicas: IXMLCaracteristicas;
procedure Set_Nombre(Value: WideString);
public
procedure AfterConstruction; override;
end;
{ TXMLCaracteristicas }
TXMLCaracteristicas = class(TXMLNodeCollection, IXMLCaracteristicas)
protected
{ IXMLCaracteristicas }
function Get_Propiedades(Index: Integer): IXMLPropiedades;
function Add: IXMLPropiedades;
function Insert(const Index: Integer): IXMLPropiedades;
public
procedure AfterConstruction; override;
end;
{ TXMLPropiedades }
TXMLPropiedades = class(TXMLNode, IXMLPropiedades)
protected
{ IXMLPropiedades }
function Get_Id: WideString;
function Get_Value: WideString;
procedure Set_Id(Value: WideString);
procedure Set_Value(Value: WideString);
end;
{ Global Functions }
function GetreportesDinamicos(Doc: IXMLDocument): IXMLReportesDinamicos;
function LoadreportesDinamicos(const FileName: WideString): IXMLReportesDinamicos;
function NewreportesDinamicos: IXMLReportesDinamicos;
const
TargetNamespace = '';
implementation
{ Global Functions }
function GetreportesDinamicos(Doc: IXMLDocument): IXMLReportesDinamicos;
begin
Result := Doc.GetDocBinding('reportesDinamicos', TXMLReportesDinamicos, TargetNamespace) as IXMLReportesDinamicos;
end;
function LoadreportesDinamicos(const FileName: WideString): IXMLReportesDinamicos;
begin
Result := LoadXMLDocument(FileName).GetDocBinding('reportesDinamicos', TXMLReportesDinamicos, TargetNamespace) as IXMLReportesDinamicos;
end;
function NewreportesDinamicos: IXMLReportesDinamicos;
begin
Result := NewXMLDocument.GetDocBinding('reportesDinamicos', TXMLReportesDinamicos, TargetNamespace) as IXMLReportesDinamicos;
end;
{ TXMLReportesDinamicos }
procedure TXMLReportesDinamicos.AfterConstruction;
begin
RegisterChildNode('listaImpuestos', TXMLListaImpuestos);
RegisterChildNode('propiedadesReportes', TXMLPropiedadesReportes);
inherited;
end;
function TXMLReportesDinamicos.Get_ListaImpuestos: IXMLListaImpuestos;
begin
Result := ChildNodes['listaImpuestos'] as IXMLListaImpuestos;
end;
function TXMLReportesDinamicos.Get_PropiedadesReportes: IXMLPropiedadesReportes;
begin
Result := ChildNodes['propiedadesReportes'] as IXMLPropiedadesReportes;
end;
{ TXMLListaImpuestos }
procedure TXMLListaImpuestos.AfterConstruction;
begin
RegisterChildNode('impuesto', TXMLImpuesto);
ItemTag := 'impuesto';
ItemInterface := IXMLImpuesto;
inherited;
end;
function TXMLListaImpuestos.Get_Impuesto(Index: Integer): IXMLImpuesto;
begin
Result := List[Index] as IXMLImpuesto;
end;
function TXMLListaImpuestos.Add: IXMLImpuesto;
begin
Result := AddItem(-1) as IXMLImpuesto;
end;
function TXMLListaImpuestos.Insert(const Index: Integer): IXMLImpuesto;
begin
Result := AddItem(Index) as IXMLImpuesto;
end;
{ TXMLImpuesto }
function TXMLImpuesto.Get_Clave: WideString;
begin
Result := AttributeNodes['clave'].Text;
end;
procedure TXMLImpuesto.Set_Clave(Value: WideString);
begin
SetAttribute('clave', Value);
end;
function TXMLImpuesto.Get_Descripcion: WideString;
begin
Result := AttributeNodes['descripcion'].Text;
end;
procedure TXMLImpuesto.Set_Descripcion(Value: WideString);
begin
SetAttribute('descripcion', Value);
end;
{ TXMLPropiedadesReportes }
procedure TXMLPropiedadesReportes.AfterConstruction;
begin
RegisterChildNode('reporte', TXMLReporte);
ItemTag := 'reporte';
ItemInterface := IXMLReporte;
inherited;
end;
function TXMLPropiedadesReportes.Get_Reporte(Index: Integer): IXMLReporte;
begin
Result := List[Index] as IXMLReporte;
end;
function TXMLPropiedadesReportes.Add: IXMLReporte;
begin
Result := AddItem(-1) as IXMLReporte;
end;
function TXMLPropiedadesReportes.Insert(const Index: Integer): IXMLReporte;
begin
Result := AddItem(Index) as IXMLReporte;
end;
{ TXMLReporte }
procedure TXMLReporte.AfterConstruction;
begin
RegisterChildNode('caracteristicas', TXMLCaracteristicas);
inherited;
end;
function TXMLReporte.Get_Nombre: WideString;
begin
Result := ChildNodes['nombre'].Text;
end;
procedure TXMLReporte.Set_Nombre(Value: WideString);
begin
ChildNodes['nombre'].NodeValue := Value;
end;
function TXMLReporte.Get_Caracteristicas: IXMLCaracteristicas;
begin
Result := ChildNodes['caracteristicas'] as IXMLCaracteristicas;
end;
{ TXMLCaracteristicas }
procedure TXMLCaracteristicas.AfterConstruction;
begin
RegisterChildNode('propiedades', TXMLPropiedades);
ItemTag := 'propiedades';
ItemInterface := IXMLPropiedades;
inherited;
end;
function TXMLCaracteristicas.Get_Propiedades(Index: Integer): IXMLPropiedades;
begin
Result := List[Index] as IXMLPropiedades;
end;
function TXMLCaracteristicas.Add: IXMLPropiedades;
begin
Result := AddItem(-1) as IXMLPropiedades;
end;
function TXMLCaracteristicas.Insert(const Index: Integer): IXMLPropiedades;
begin
Result := AddItem(Index) as IXMLPropiedades;
end;
{ TXMLPropiedades }
function TXMLPropiedades.Get_Id: WideString;
begin
Result := AttributeNodes['id'].Text;
end;
procedure TXMLPropiedades.Set_Id(Value: WideString);
begin
SetAttribute('id', Value);
end;
function TXMLPropiedades.Get_Value: WideString;
begin
Result := AttributeNodes['value'].Text;
end;
procedure TXMLPropiedades.Set_Value(Value: WideString);
begin
SetAttribute('value', Value);
end;
end.
delphi
================================Como leer el XML================================
var
xml: TXMLDocument;
lector:IXMLReportesDinamicos;
listaPropiedades : IJclAnsiStrAnsiStrMap;
xml := TXMLDocument.Create(TComponent.Create(nil));
xml.FileName := '..\..\propertiesReportes.xml';
xml.Active := True;
lector := GetreportesDinamicos(xml);
//Método que recibe un tag del xml para localizarlo (puede ser un formulario como lo maneje yo) y obtener sus propiedades
function getPropiedadesReporte(nombreReporte: WString): WString;
var
i:integer;
y:integer;
begin
//Como ven acá creo mi Has Map de tamaño 50
listaPropiedades := TJclAnsiStrAnsiStrHashMap.Create(50);
result:='';
try
for i:= 0 to impuesto.PropiedadesReportes.Count-1 do
begin
if lector.PropiedadesReportes.Nombre=nombreReporte then
begin
for y :=0 to lector.PropiedadesReportes.Caracteristicas.Count-1 do
begin
//Escribo en mi hashMap (llave-valor)
listaPropiedades.putvalue(
lector.PropiedadesReportes.Caracteristicas.Propiedades[y].Id,
lector.PropiedadesReportes.Caracteristicas.Propiedades[y].Value);
end;
break;
end;
end;
except
result:='';
end;
end;
//Metodo el cual recibe como parámetro un id que si s edan cuenta es la llave que incruste en mi Hash Map para realizar al búsqueda retornandome el valor de esa llave
function getPropertiValue(id: wstring): wstring;
begin
if listaPropiedades.ContainsKey(id) then
result:=string(listaPropiedades.GetValue(id));
//Esta parte la pueden implementar es para iterar mi Has Map y devolver todo el contenido de este
{iterador := listaPropiedades.KeySet.First;
while iterador.HasNext do
begin
key:=iterador.Next;
cadetalle:= key +' :: '+listaPropiedades.Items[key];
end;}
end;
Por último añado que esto lo use con el XML Data Binding propio d eDelphi, los componentes Jedi http://jvcl.delphi-jedi.org/ para los Hash Map que a propósito traen una librería para integrar nuestro proyecto a Subversión con el uso de TortoiseSVN que a decir verdad es de mucha utilidad tener esta opción dentro del IDE que creo en las ultimas versiones de Delphi ya viene integrado pero para quienes manejan pro ejemplo la 2009 o 2010 les vendrá muy bien