2011-11-23 7 views
7

Tengo una clase con accesorios publicados que serializo en XML.Obtener un valor attribue de la propiedad específica

MyAttr = class(TCustomAttribute) 
private 
    FName: string; 
public 
    constructor Create(const Name: string); 
    property Name: string read FName write FName; 
end; 

MyClass = class(TPersistent) 
private 
    FClassCaption: string; 
published 
    [MyAttr('Class')] 
    property ClassCaption: string read FClassCaption write FClassCaption; 
end; 

Dado que el tamaño XML es crucial, utilizo atributos para dar nombre más corto de la propiedad (es decir, no puedo definir una propiedad denominada 'clase'). serialización implementa de la siguiente manera:

lPropCount := GetPropList(PTypeInfo(Obj.ClassInfo), lPropList); 
for i := 0 to lPropCount - 1 do begin 
    lPropInfo := lPropList^[i]; 
    lPropName := string(lPropInfo^.Name); 

    if IsPublishedProp(Obj, lPropName) then begin 
    ItemNode := RootNode.AddChild(lPropName); 
    ItemNode.NodeValue := VarToStr(GetPropValue(Obj, lPropName, False)); 
    end; 
end; 

necesito perfectas condiciones: si la propiedad marcada con MyAttr, obtener "MyAttr.Name" en lugar de "lPropInfo^.Nombre".

Respuesta

5

Puede utilizar esta función para obtener el nombre del atributo de la propiedad dada (lo escribió en un minuto, probablemente necesita un poco de optimización):

uses 
    SysUtils, 
    Rtti, 
    TypInfo; 

function GetPropAttribValue(ATypeInfo: Pointer; const PropName: string): string; 
var 
    ctx: TRttiContext; 
    typ: TRttiType; 
    Aprop: TRttiProperty; 
    attr: TCustomAttribute; 
begin 
    Result := ''; 

    ctx := TRttiContext.Create; 

    typ := ctx.GetType(ATypeInfo); 

    for Aprop in typ.GetProperties do 
    begin 
    if (Aprop.Visibility = mvPublished) and (SameText(PropName, Aprop.Name)) then 
    begin  
     for attr in AProp.GetAttributes do 
     begin 
     if attr is MyAttr then 
     begin 
      Result := MyAttr(attr).Name; 
      Exit; 
     end; 
     end; 
     Break; 
    end; 
    end; 
end; 

Llámelo como esto:

sAttrName:= GetPropAttribValue(obj.ClassInfo, lPropName); 

Entonces, si esta función devuelve una cadena vacía, significa que la propiedad no está marcada con MyAttr y luego debe usar "lPropInfo^.Name".

Cuestiones relacionadas