internal XmlNodeOrder ComparePosition( XPathNodePointer other ) {
//Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:ComparePosition(other)");
RealFoliate();
other.RealFoliate();
Debug.Assert( other != null );
if ( IsSamePosition( other ) )
return XmlNodeOrder.Same;
XmlNode curNode1 = null, curNode2 = null;
//deal with namespace node first
if ( this.NodeType == XPathNodeType.Namespace && other.NodeType == XPathNodeType.Namespace ) {
if ( this._parentOfNS == other._parentOfNS )
return this.CompareNamespacePosition( other );
//if not from the same parent
curNode1 = this._parentOfNS;
curNode2 = other._parentOfNS;
}
else if ( this.NodeType == XPathNodeType.Namespace ) {
Debug.Assert( other.NodeType != XPathNodeType.Namespace );
if ( this._parentOfNS == other._node ) {
//from the same region, NS nodes come before all other nodes
if ( other._column == null )
return XmlNodeOrder.After;
else
return XmlNodeOrder.Before;
}
//if not from the same region
curNode1 = this._parentOfNS;
curNode2 = other._node;
}
else if ( other.NodeType == XPathNodeType.Namespace ) {
Debug.Assert( this.NodeType != XPathNodeType.Namespace );
if ( this._node == other._parentOfNS ) {
//from the same region
if ( this._column == null )
return XmlNodeOrder.Before;
else
return XmlNodeOrder.After;
}
//if not from the same region
curNode1 = this._node;
curNode2 = other._parentOfNS;
}
else {
if ( this._node == other._node ) {
//compare within the same region
if ( this._column == other._column ) {
//one is the children of the other
Debug.Assert( this._fOnValue != other._fOnValue );
if ( this._fOnValue )
return XmlNodeOrder.After;
else
return XmlNodeOrder.Before;
}
else {
Debug.Assert( this.Row == other.Row ); //in the same row
if ( this._column == null )
return XmlNodeOrder.Before;
else if ( other._column == null )
return XmlNodeOrder.After;
else if ( this._column.Ordinal < other._column.Ordinal )
return XmlNodeOrder.Before;
else
return XmlNodeOrder.After;
}
}
curNode1 = this._node;
curNode2 = other._node;
}
Debug.Assert( curNode1 != null );
Debug.Assert( curNode2 != null );
if (curNode1 == null || curNode2 == null) {
return XmlNodeOrder.Unknown;
}
int depth1 = -1, depth2 = -1;
XmlNode root1 = XPathNodePointer.GetRoot( curNode1, ref depth1 );
XmlNode root2 = XPathNodePointer.GetRoot( curNode2, ref depth2 );
if ( root1 != root2 )
return XmlNodeOrder.Unknown;
if ( depth1 > depth2 ) {
while ( curNode1 != null && depth1 > depth2 ) {
curNode1 = ( ( curNode1.NodeType == XmlNodeType.Attribute ) ? ( ((XmlAttribute)curNode1).OwnerElement ) : ( curNode1.ParentNode ) );
depth1--;
}
if ( curNode1 == curNode2 )
return XmlNodeOrder.After;
}
else if ( depth2 > depth1 ) {
while ( curNode2 != null && depth2 > depth1 ) {
curNode2 = ( ( curNode2.NodeType == XmlNodeType.Attribute ) ? ( ((XmlAttribute)curNode2).OwnerElement ) : ( curNode2.ParentNode ) );
depth2--;
}
if ( curNode1 == curNode2 )
return XmlNodeOrder.Before;
}
XmlNode parent1 = GetParent(curNode1);
XmlNode parent2 = GetParent(curNode2);
XmlNode nextNode = null;
while ( parent1 != null && parent2 != null ) {
if ( parent1 == parent2 ) {
while (curNode1 != null ) {
nextNode = curNode1.NextSibling;
if ( nextNode == curNode2 )
return XmlNodeOrder.Before;
curNode1 = nextNode;
}
return XmlNodeOrder.After;
}
curNode1 = parent1;
curNode2 = parent2;
parent1 = curNode1.ParentNode;
parent2 = curNode2.ParentNode;
}
//logically, we shouldn't reach here
Debug.Assert( false );
return XmlNodeOrder.Unknown;
}