xpath.pp: Honor axis direction when filtering step result with predicates. For reverse axes, ContextPosition is now relative to the last node of the set. The third argument of TXPathExprNode.EvalPredicate() is redundant and has been removed.

git-svn-id: trunk@13129 -
This commit is contained in:
sergei 2009-05-10 19:32:22 +00:00
parent 828afdf74c
commit 7a478e64c2

View File

@ -101,7 +101,7 @@ type
TXPathExprNode = class TXPathExprNode = class
protected protected
function EvalPredicate(AContext: TXPathContext; function EvalPredicate(AContext: TXPathContext;
AEnvironment: TXPathEnvironment; APosition: Integer): Boolean; AEnvironment: TXPathEnvironment): Boolean;
public public
function Evaluate(AContext: TXPathContext; function Evaluate(AContext: TXPathContext;
AEnvironment: TXPathEnvironment): TXPathVariable; virtual; abstract; AEnvironment: TXPathEnvironment): TXPathVariable; virtual; abstract;
@ -586,14 +586,14 @@ end;
{ XPath parse tree classes } { XPath parse tree classes }
function TXPathExprNode.EvalPredicate(AContext: TXPathContext; function TXPathExprNode.EvalPredicate(AContext: TXPathContext;
AEnvironment: TXPathEnvironment; APosition: Integer): Boolean; AEnvironment: TXPathEnvironment): Boolean;
var var
resvar: TXPathVariable; resvar: TXPathVariable;
begin begin
resvar := Evaluate(AContext, AEnvironment); resvar := Evaluate(AContext, AEnvironment);
try try
if resvar.InheritsFrom(TXPathNumberVariable) then if resvar.InheritsFrom(TXPathNumberVariable) then
Result := resvar.AsNumber = APosition + 1 // TODO: trunc/round? Result := resvar.AsNumber = AContext.ContextPosition // TODO: trunc/round?
else else
Result := resvar.AsBoolean; Result := resvar.AsBoolean;
finally finally
@ -1030,7 +1030,7 @@ begin
for j := 0 to FPredicates.Count - 1 do for j := 0 to FPredicates.Count - 1 do
begin begin
DoAdd := TXPathExprNode(FPredicates[j]).EvalPredicate(NewContext, DoAdd := TXPathExprNode(FPredicates[j]).EvalPredicate(NewContext,
AEnvironment, i); AEnvironment);
if not DoAdd then if not DoAdd then
Break; Break;
end; end;
@ -1258,10 +1258,16 @@ var
Predicate := TXPathExprNode(AStep.Predicates[i]); Predicate := TXPathExprNode(AStep.Predicates[i]);
for j := 0 to StepNodes.Count - 1 do for j := 0 to StepNodes.Count - 1 do
begin begin
// ContextPosition must honor the axis direction
if AStep.Axis in [axisAncestor, axisAncestorOrSelf,
axisPreceding, axisPrecedingSibling] then
NewContext.ContextPosition := StepNodes.Count - j
else
NewContext.ContextPosition := j+1;
Node := TDOMNode(StepNodes[j]); Node := TDOMNode(StepNodes[j]);
NewContext.ContextNode := Node; NewContext.ContextNode := Node;
Inc(NewContext.ContextPosition); if Predicate.EvalPredicate(NewContext, AEnvironment) then
if Predicate.EvalPredicate(NewContext, AEnvironment, j) then
NewStepNodes.Add(Node); NewStepNodes.Add(Node);
end; end;
finally finally