QMathExpr 可以方便的实现表达式的计算,将它与 QJson 结合在一起,就可以对内容进行加工处理,为程序的实现提供更大的灵活性。同样的,你可以同样将 QXML/QMsgPack 一样封装下,为其加上 QMathExpr 的支持。
TQJsonVarHelper = class helper for TQJson
private
procedure DoGetJsonVar(Sender: IQMathExpression; const AVarName: String;
var AVar: TQMathVar);
class procedure DoGetJsonValue(Sender: TObject; AVar: TQMathVar); static;
function GetAsExpression: Variant;
public
property AsExpression: Variant read GetAsExpression;
end;
{ TQJsonVarHelper }
class procedure TQJsonVarHelper.DoGetJsonValue(Sender: TObject;
AVar: TQMathVar);
var
AItem: TQJson;
begin
AItem := TQJson(AVar.Tag);
if Assigned(AItem) then
AVar.Value := AItem.AsVariant
else
AVar.Value := Unassigned;
end;
procedure TQJsonVarHelper.DoGetJsonVar(Sender: IQMathExpression;
const AVarName: String; var AVar: TQMathVar);
var
AJson, AItem: TQJson;
begin
AJson := TQJson(Sender.Tag);
if StartWithW(PWideChar(AVarName), '$', false) then
AItem := AJson.ItemByPath(RightStrW(AVarName,
Length(AVarName) - 1, false))
else
AItem := AJson.ItemByPath(AVarName);
if Assigned(AItem) then
begin
AVar := Sender.Add(AVarName, 0, 0, DoGetJsonValue);
AVar.Tag := AItem;
end;
end;
function TQJsonVarHelper.GetAsExpression: Variant;
var
AExpr: IQMathExpression;
begin
AExpr := TQMathExpression.Create;
AExpr.OnLookupMissed := DoGetJsonVar;
AExpr.Tag := Parent;
Result := AExpr.Eval(Value);
end;
调用示例:
var
AJsonVars:TQJson;
begin
AJsonVars := TQJson.Create;
AJsonVars.Parse('{"a":{"b":1,"c":2},"f":20}');
// d的值通过表达式计算赋值
AJsonVars.Add('d').AsString := 'f+$a.c';
ShowMessage(VarToStr(AJsonVars.ItemByName('d').AsExpression));