2011-11-23 222 views
7

我有一個已發佈道具的類,我將其序列化爲XML。由於XML大小至關重要,因此我使用屬性給屬性賦予較短的名稱(即,我無法定義名爲'Class'的屬性)。 序列化實現方式如下:獲取特定屬性的屬性值

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財產,得到 「MyAttr.Name」,而不是 「lPropInfo ^請將.Name」 的。

回答

5

您可以使用此功能從給定的屬性讓你的屬性名稱(寫在一分鐘內,可能需要一些優化):

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); 

所以如果這個函數返回空字符串,這意味着屬性沒有用MyAttr標記,然後你需要使用「lPropInfo^.Name」。