private int numberAny(Processor processor, ActionFrame frame) {
int result = 0;
// Our current point will be our end point in this search
XPathNavigator endNode = frame.Node;
if(endNode.NodeType == XPathNodeType.Attribute || endNode.NodeType == XPathNodeType.Namespace) {
endNode = endNode.Clone();
endNode.MoveToParent();
}
XPathNavigator startNode = endNode.Clone();
if(this.fromKey != Compiler.InvalidQueryKey) {
bool hitFrom = false;
// First try to find start by traversing up. This gives the best candidate or we hit root
do{
if(processor.Matches(startNode, this.fromKey)) {
hitFrom = true;
break;
}
}while(startNode.MoveToParent());
Debug.Assert(
processor.Matches(startNode, this.fromKey) || // we hit 'from' or
startNode.NodeType == XPathNodeType.Root // we are at root
);
// from this point (matched parent | root) create descendent quiery:
// we have to reset 'result' on each 'from' node, because this point can' be not last from point;
XPathNodeIterator sel = startNode.SelectDescendants(XPathNodeType.All, /*matchSelf:*/ true);
while (sel.MoveNext()) {
if(processor.Matches(sel.Current, this.fromKey)) {
hitFrom = true;
result = 0;
}
else if(MatchCountKey(processor, frame.Node, sel.Current)) {
result ++;
}
if(sel.Current.IsSamePosition(endNode)) {
break;
}
}
if(! hitFrom) {
result = 0;
}
}
else {
// without 'from' we startting from the root
startNode.MoveToRoot();
XPathNodeIterator sel = startNode.SelectDescendants(XPathNodeType.All, /*matchSelf:*/ true);
// and count root node by itself
while (sel.MoveNext()) {
if (MatchCountKey(processor, frame.Node, sel.Current)) {
result ++;
}
if (sel.Current.IsSamePosition(endNode)) {
break;
}
}
}
return result;
}