[QMathExpr]为 QJson 增加 QMathExpr 支持

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

分享到: