Browse Source

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 -
sergei 16 years ago
parent
commit
7a478e64c2
1 changed files with 12 additions and 6 deletions
  1. 12 6
      packages/fcl-xml/src/xpath.pp

+ 12 - 6
packages/fcl-xml/src/xpath.pp

@@ -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, j) then
+          if Predicate.EvalPredicate(NewContext, AEnvironment) then
             NewStepNodes.Add(Node);
             NewStepNodes.Add(Node);
         end;
         end;
       finally
       finally