2011-11-23 20 views
7

XMLにシリアライズした公開された小道具を持つクラスがあります。特定のプロパティの属性値を取得する

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; 

XMLサイズが重要なので、属性を使用してプロパティの名前を短縮します(つまり、「クラス」という名前のプロパティを定義できません)。 シリアライゼーションは、次のように実装:

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; 

のように私は条件を必要とする:プロパティはMyAttrでマークされた場合は、 "lPropInfo^.nameの" の代わりに "MyAttr.Name" を取得します。

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; 

このようにそれを呼び出します:

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

答えて

5

あなたが与えられたプロパティから自分の属性名を取得するには、この機能を使用することができます(おそらくいくつかの最適化を必要とする分にそれを書きました)したがって、この関数が空の文字列を返す場合は、プロパティにMyAttrが設定されていないことを意味し、 "lPropInfo^.Name"を使用する必要があります。

関連する問題