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 -
This commit is contained in:
sergei 2010-07-28 15:25:19 +00:00
parent 95f74fbb11
commit 1876fb1c74

View File

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