// equal & ! attribute then move // "a/b/c" pointer from a move to b // return true if reach c and c is an element and c is the axis internal bool MoveToChild(string name, string URN, int depth, ForwardAxis parent) { // an attribute can never be the same as an element if (Asttree.IsAttribute(this.curNode)) { return false; } // either moveToParent or moveToChild status will have to be changed into unmatch... if (this.isMatch) { this.isMatch = false; } if (! AxisStack.Equal (this.curNode.Name, this.curNode.Urn, name, URN)) { return false; } if (this.curDepth == -1) { SetDepth (depth); } else if (depth > this.curDepth) { return false; } // matched ... if (this.curNode == parent.TopNode) { this.isMatch = true; return true; } // move down this.curNode DoubleLinkAxis nowNode = (DoubleLinkAxis) (this.curNode.Next); if (Asttree.IsAttribute (nowNode)) { this.isMatch = true; // for attribute return false; } this.curNode = nowNode; this.curDepth ++; return false; }
// "a/b/c" pointer from b move to a // needn't change even tree structure changes internal void MoveToParent(int depth, ForwardAxis parent) { // "a/b/c", trying to match b (current node), but meet the end of a, so move pointer to a if ( depth == this.curDepth - 1 ) { // really need to move the current node pointer to parent // what i did here is for seperating the case of IsDss or only IsChild // bcoz in the first case i need to expect "a" from random depth // -1 means it doesn't expect some specific depth (referecing the dealing to -1 in movetochild method // while in the second case i can't change the root depth which is 1. if ((this.curNode.Input == parent.RootNode ) && (parent.IsDss)) { this.curNode = parent.RootNode; this.rootDepth = this.curDepth = -1; return; } else if (this.curNode.Input != null) { // else cur-depth --, cur-node change this.curNode = (DoubleLinkAxis) (this.curNode.Input); this.curDepth --; return; } else return; } // "a/b/c", trying to match b (current node), but meet the end of x (another child of a) // or maybe i matched, now move out the current node // or move out after failing to match attribute // the node i m next expecting is still the current node else if (depth == this.curDepth) { // after matched or [2] failed in matching attribute if (this.isMatch) { this.isMatch = false; } } return; // this node is still what i am expecting // ignore }
// XXX: needs to be fixed private void update_iterator() { switch (_axis) { case Type.NONE: if (node_test() is AttributeTest) { _iterator = new AttributeAxis(); } else { _iterator = new ChildAxis(); } break; case Type.CHILD: _iterator = new ChildAxis(); break; case Type.DESCENDANT: _iterator = new DescendantAxis(); break; case Type.FOLLOWING_SIBLING: _iterator = new FollowingSiblingAxis(); break; case Type.FOLLOWING: _iterator = new FollowingAxis(); break; case Type.AT_SYM: case Type.ATTRIBUTE: _iterator = new AttributeAxis(); break; case Type.SELF: _iterator = new SelfAxis(); break; case Type.DESCENDANT_OR_SELF: _iterator = new DescendantOrSelfAxis(); break; case Type.NAMESPACE: throw new StaticError("XPST0010", "namespace axis not implemented"); default: Debug.Assert(false); break; } }
// instructor public AxisStack(ForwardAxis faxis, ActiveAxis parent) { _subtree = faxis; _stack = new ArrayList(); _parent = parent; // need to use its contextdepth each time.... // improvement: // if ! isDss, there has nothing to do with Push/Pop, only one copy each time will be kept // if isDss, push and pop each time.... if (!faxis.IsDss) { // keep an instance this.Push(1); // context depth + 1 } // else just keep stack empty }