From 1876fb1c745a75deeabc3124fd2599d626387280 Mon Sep 17 00:00:00 2001 From: sergei Date: Wed, 28 Jul 2010 15:25:19 +0000 Subject: [PATCH] XPath: now when predicate filtering is no longer dependent on axis, it becomes possible to use the same code for TStep and TXPathFilterNode. Inherited TStep from TXPathFilterNode, removed duplicating code. git-svn-id: trunk@15654 - --- packages/fcl-xml/src/xpath.pp | 78 +++++++---------------------------- 1 file changed, 15 insertions(+), 63 deletions(-) diff --git a/packages/fcl-xml/src/xpath.pp b/packages/fcl-xml/src/xpath.pp index bb99beb5ba..60a892fc23 100644 --- a/packages/fcl-xml/src/xpath.pp +++ b/packages/fcl-xml/src/xpath.pp @@ -233,12 +233,15 @@ type end; + TNodeSet = TFPList; + // Filter node (for [20]) TXPathFilterNode = class(TXPathExprNode) private - FExpr: TXPathExprNode; + FLeft: TXPathExprNode; FPredicates: TXPathNodeArray; + procedure ApplyPredicates(Nodes: TNodeSet; AEnvironment: TXPathEnvironment); public constructor Create(AExpr: TXPathExprNode); destructor Destroy; override; @@ -257,21 +260,15 @@ type TNodeTestType = (ntAnyPrincipal, ntName, ntTextNode, ntCommentNode, ntPINode, ntAnyNode); - TNodeSet = TFPList; - - TStep = class(TXPathExprNode) + TStep = class(TXPathFilterNode) private procedure SelectNodes(ANode: TDOMNode; out ResultNodes: TNodeSet); - procedure ApplyPredicates(Nodes: TNodeSet; AEnvironment: TXPathEnvironment); public - FLeft: TXPathExprNode; Axis: TAxis; NodeTestType: TNodeTestType; NodeTestString: DOMString; NSTestString: DOMString; - Predicates: TXPathNodeArray; constructor Create(aAxis: TAxis; aTest: TNodeTestType); - destructor Destroy; override; function Evaluate(AContext: TXPathContext; AEnvironment: TXPathEnvironment): TXPathVariable; override; end; @@ -1042,14 +1039,14 @@ end; constructor TXPathFilterNode.Create(AExpr: TXPathExprNode); begin inherited Create; - FExpr := AExpr; + FLeft := AExpr; end; destructor TXPathFilterNode.Destroy; var i: Integer; begin - FExpr.Free; + FLeft.Free; for i := 0 to High(FPredicates) do FPredicates[i].Free; inherited Destroy; @@ -1058,65 +1055,20 @@ end; function TXPathFilterNode.Evaluate(AContext: TXPathContext; AEnvironment: TXPathEnvironment): TXPathVariable; var - ExprResult: TXPathVariable; - NodeSet, NewNodeSet: TNodeSet; - i, j: Integer; - CurContextNode: TDOMNode; - NewContext: TXPathContext; - DoAdd: Boolean; + NodeSet: TNodeSet; begin - ExprResult := FExpr.Evaluate(AContext, AEnvironment); - NewContext := nil; - try - NodeSet := ExprResult.AsNodeSet; - NewContext := TXPathContext.Create(nil, 0, NodeSet.Count); - NewNodeSet := TNodeSet.Create; - try - for i := 0 to NodeSet.Count - 1 do - begin - CurContextNode := TDOMNode(NodeSet[i]); - NewContext.ContextNode := CurContextNode; - Inc(NewContext.ContextPosition); - DoAdd := True; - for j := 0 to High(FPredicates) do - begin - DoAdd := FPredicates[j].EvalPredicate(NewContext, - AEnvironment); - if not DoAdd then - Break; - end; - if DoAdd then - NewNodeSet.Add(CurContextNode); - end; - except - NewNodeSet.Free; - raise; - end; - Result := TXPathNodeSetVariable.Create(NewNodeSet); - finally - NewContext.Free; - ExprResult.Release; - end; + Result := FLeft.Evaluate(AContext, AEnvironment); + NodeSet := Result.AsNodeSet; + ApplyPredicates(NodeSet, AEnvironment); end; constructor TStep.Create(aAxis: TAxis; aTest: TNodeTestType); begin - inherited Create; Axis := aAxis; NodeTestType := aTest; end; -destructor TStep.Destroy; -var - i: Integer; -begin - FLeft.Free; - for i := 0 to High(Predicates) do - Predicates[i].Free; - inherited destroy; -end; - procedure TStep.SelectNodes(ANode: TDOMNode; out ResultNodes: TNodeSet); var Node, Node2: TDOMNode; @@ -1305,12 +1257,12 @@ end; by nil. After one filter has been applied, Nodes is packed, and the next filter will be processed. } -procedure TStep.ApplyPredicates(Nodes: TNodeSet; AEnvironment: TXPathEnvironment); +procedure TXPathFilterNode.ApplyPredicates(Nodes: TNodeSet; AEnvironment: TXPathEnvironment); var i, j: Integer; NewContext: TXPathContext; begin - for i := 0 to High(Predicates) do + for i := 0 to High(FPredicates) do begin NewContext := TXPathContext.Create(nil, 0, Nodes.Count); try @@ -1318,7 +1270,7 @@ begin begin NewContext.ContextPosition := j+1; NewContext.ContextNode := TDOMNode(Nodes[j]); - if not Predicates[i].EvalPredicate(NewContext, AEnvironment) then + if not FPredicates[i].EvalPredicate(NewContext, AEnvironment) then Nodes[j] := nil; end; Nodes.Pack; @@ -1893,7 +1845,7 @@ begin Axis := axisChild; Result := ParseNodeTest(Axis); - ParsePredicates(Result.Predicates); + ParsePredicates(Result.FPredicates); end; end;