2011-11-23 225 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”。