Преглед на файлове

2003-07-28 Piers Haken <[email protected]>

	* DefaultContext.cs: better handling of null argument lists
	* XPathNavigator.cs: implement ComparePosition

svn path=/trunk/mcs/; revision=16817
Piers Haken преди 22 години
родител
ревизия
79ebd61c28

+ 5 - 0
mcs/class/System.XML/System.Xml.XPath/ChangeLog

@@ -1,3 +1,8 @@
+2003-07-28  Piers Haken	<[email protected]>
+
+	* DefaultContext.cs: better handling of null argument lists
+	* XPathNavigator.cs: implement ComparePosition
+
 2003-07-28  Piers Haken	<[email protected]>
 
 	* Expression.cs: boolean operators: handle comparing .Any better

+ 9 - 3
mcs/class/System.XML/System.Xml.XPath/DefaultContext.cs

@@ -287,7 +287,9 @@ namespace System.Xml.XPath
 		public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
 		public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
 		{
-			BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext);
+			if (args.Length == 0)
+				return docContext.LocalName;
+			BaseIterator iter = (BaseIterator) args [0];
 			if (iter == null || !iter.MoveNext ())
 				return "";
 			return iter.Current.LocalName;
@@ -305,7 +307,9 @@ namespace System.Xml.XPath
 		[MonoTODO]
 		public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
 		{
-			BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext);
+			if (args.Length == 0)
+				return docContext.NamespaceURI;
+			BaseIterator iter = (BaseIterator) args [0];
 			if (iter == null || !iter.MoveNext ())
 				return "";
 			return iter.Current.NamespaceURI;	// TODO: should the namespace be expanded wrt. the given context?
@@ -323,7 +327,9 @@ namespace System.Xml.XPath
 		[MonoTODO]
 		public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
 		{
-			BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext);
+			if (args.Length == 0)
+				return docContext.Name;
+			BaseIterator iter = (BaseIterator) args [0];
 			if (iter == null || !iter.MoveNext ())
 				return "";
 			return iter.Current.Name;

+ 85 - 1
mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs

@@ -48,6 +48,18 @@ namespace System.Xml.XPath
 
 		public abstract string XmlLang { get; }
 
+		int Depth
+		{
+			get
+			{
+				int cLevels = 0;
+				XPathNavigator nav = Clone ();
+				while (nav.MoveToParent ())
+					cLevels ++;
+				return cLevels;
+			}
+		}
+
 		#endregion
 
 		#region Methods
@@ -57,7 +69,79 @@ namespace System.Xml.XPath
 		[MonoTODO]
 		public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
 		{
-			throw new NotImplementedException ();
+			if (IsSamePosition (nav))
+				return XmlNodeOrder.Same;
+
+			XPathNavigator nav1 = Clone ();
+			XPathNavigator nav2 = nav.Clone ();
+
+			int nDepth1 = nav1.Depth;
+			int nDepth2 = nav2.Depth;
+
+			if (nDepth1 > nDepth2)
+			{
+				while (nDepth1 > nDepth2)
+				{
+					nav1.MoveToParent ();
+					nDepth1 --;
+				}
+				if (nav1.IsSamePosition (nav2))
+					return XmlNodeOrder.After;
+			}
+			else if (nDepth1 < nDepth2)
+			{
+				while (nDepth1 < nDepth2)
+				{
+					nav2.MoveToParent ();
+					nDepth2 --;
+				}
+				if (nav1.IsSamePosition (nav2))
+					return XmlNodeOrder.Before;
+			}
+
+			XPathNavigator parent1 = nav1.Clone ();
+			XPathNavigator parent2 = nav2.Clone ();
+			while (parent1.MoveToParent () && parent2.MoveToParent ())
+			{
+				if (parent1.IsSamePosition (parent2))
+				{
+					// the ordering is namespace, attribute, children
+					// assume that nav1 is before nav2, find counter-example
+					if (nav1.NodeType == XPathNodeType.Namespace)
+					{
+						if (nav2.NodeType == XPathNodeType.Namespace)
+						{
+							// match namespaces
+							while (nav2.MoveToNextNamespace ())
+								if (nav2.IsSamePosition (nav1))
+									return XmlNodeOrder.After;
+						}
+					}
+					else if (nav1.NodeType == XPathNodeType.Attribute)
+					{
+						if (nav2.NodeType == XPathNodeType.Namespace)
+							return XmlNodeOrder.After;
+						else if (nav2.NodeType == XPathNodeType.Attribute)
+						{
+							// match attributes
+							while (nav2.MoveToNextAttribute ())
+								if (nav2.IsSamePosition (nav1))
+									return XmlNodeOrder.After;
+						}
+					}
+					else
+					{
+						// match children
+						while (nav2.MoveToNext ())
+							if (nav2.IsSamePosition (nav1))
+								return XmlNodeOrder.After;
+					}
+					return XmlNodeOrder.Before;
+				}
+				nav1.MoveToParent ();
+				nav2.MoveToParent ();
+			}
+			return XmlNodeOrder.Unknown;
 		}
 
 		public virtual XPathExpression Compile (string xpath)