mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 11:49:24 +02:00
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:
parent
95f74fbb11
commit
1876fb1c74
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user