Bläddra i källkod

2003-10-01 Atsushi Enomoto <[email protected]>

	* Added DTMXPathNode.cs.
	* Fundamental changes in whole DTM stuff. Node information is now array
	  of "node struct" instead of individual arrays.

svn path=/trunk/mcs/; revision=18460
Atsushi Eno 22 år sedan
förälder
incheckning
11d202e5cd

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

@@ -1,3 +1,9 @@
+2003-10-01  Atsushi Enomoto <[email protected]>
+
+	* Added DTMXPathNode.cs.
+	* Fundamental changes in whole DTM stuff. Node information is now array
+	  of "node struct" instead of individual arrays.
+
 2003-09-21 Ben Maurer  <[email protected]>
 
 	* Pattern.cs: save the parser (will reduce memory allocation when

+ 17 - 143
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs

@@ -8,10 +8,7 @@
 //
 using System;
 using System.Collections;
-using System.IO;
-using System.Text;
 using System.Xml;
-using System.Xml.Schema;
 using System.Xml.XPath;
 
 namespace Mono.Xml.XPath
@@ -23,78 +20,16 @@ namespace Mono.Xml.XPath
 #region ctor.
 
 		public DTMXPathDocument (XmlNameTable nameTable,
-			int [] firstChild__,
-			int [] parent__,
-			int [] firstAttribute__,
-			int [] previousSibling__,
-			int [] nextSibling__,
-			int [] depth__,
-			int [] position__,
-			XPathNodeType [] nodeType__,
-			string [] baseUri__,
-			bool [] isEmptyElement__,
-			string [] localName__,
-			string [] namespaceUri__,
-			string [] prefix__,
-			string [] value__,
-			string [] xmlLang__,
-			int [] namespaceNode__,
-			int [] nodeLineNumber__,
-			int [] nodeLinePosition__,
-			int [] ownerElement__,
-			int [] nextAttribute__,
-			string [] attrLocalName__,
-			string [] attrPrefix__,
-			string [] attrNsUri__,
-			string [] attrValue__,
-			object [] attrSchemaType__,
-			int [] attrLineNumber__,
-			int [] attrLinePosition__,
-			int [] nsDeclaredElement__,
-			int [] nextNsNode__,
-			string [] nsNodeName__,
-			string [] nsNodeUri__,
-			Hashtable idTable__)
+			DTMXPathLinkedNode [] nodes,
+			DTMXPathAttributeNode [] attributes,
+			DTMXPathNamespaceNode [] namespaces,
+			Hashtable idTable)
 		{
-			firstChild_ = firstChild__;
-			parent_ = parent__;
-			firstAttribute_ = firstAttribute__;
-			previousSibling_ = previousSibling__;
-			nextSibling_ = nextSibling__;
-			depth_ = depth__;
-			position_ = position__;
-			nodeType_ = nodeType__;
-			baseUri_ = baseUri__;
-			isEmptyElement_ = isEmptyElement__;
-			localName_ = localName__;
-			namespaceUri_ = namespaceUri__;
-			prefix_ = prefix__;
-			value_ = value__;
-			xmlLang_ = xmlLang__;
-			namespaceNode_ = namespaceNode__;
-			nodeLineNumber_ = nodeLineNumber__;
-			nodeLinePosition_ = nodeLinePosition__;
-
-			// Attribute
-			ownerElement_ = ownerElement__;
-			nextAttribute_ = nextAttribute__;
-			attrLocalName_ = attrLocalName__;
-			attrPrefix_ = attrPrefix__;
-			attrNsUri_ = attrNsUri__;
-			attrValue_ = attrValue__;
-			attrSchemaType_ = attrSchemaType__;
-			attrLineNumber_ = attrLineNumber__;
-			attrLinePosition_ = attrLinePosition__;
-
-			// NamespaceNode
-			nsDeclaredElement_ = nsDeclaredElement__;
-			nextNsNode_ = nextNsNode__;
-			nsNodeName_ = nsNodeName__;
-			nsNodeUri_ = nsNodeUri__;
-
-			idTable_ = idTable__;
-
 			this.nameTable = nameTable;
+			this.nodes = nodes;
+			this.attributes = attributes;
+			this.namespaces = namespaces;
+			this.idTable = idTable;
 		}
 
 #endregion
@@ -105,39 +40,11 @@ namespace Mono.Xml.XPath
 		{
 			if (root == null) {
 				root = new DTMXPathNavigator (this,
-					nameTable, 
-					firstChild_, 
-					parent_, 
-					firstAttribute_, 
-					previousSibling_, 
-					nextSibling_, 
-					depth_, 
-					position_, 
-					nodeType_, 
-					baseUri_, 
-					isEmptyElement_, 
-					localName_, 
-					namespaceUri_, 
-					prefix_, 
-					value_, 
-					xmlLang_, 
-					namespaceNode_, 
-					nodeLineNumber_, 
-					nodeLinePosition_, 
-					ownerElement_, 
-					nextAttribute_, 
-					attrLocalName_, 
-					attrPrefix_, 
-					attrNsUri_, 
-					attrValue_, 
-					attrSchemaType_, 
-					attrLineNumber_,
-					attrLinePosition_,
-					nsDeclaredElement_, 
-					nextNsNode_, 
-					nsNodeName_, 
-					nsNodeUri_, 
-					idTable_);
+					nameTable,
+					nodes,
+					attributes,
+					namespaces,
+					idTable);
 				return root;
 			} else
 				return root.Clone ();
@@ -152,45 +59,12 @@ namespace Mono.Xml.XPath
 
 #region Immutable tree fields
 
-		// Tree Node
-		int [] firstChild_;
-		int [] parent_;
-		int [] firstAttribute_;
-		int [] previousSibling_;
-		int [] nextSibling_;
-		int [] depth_;
-		int [] position_;
-		XPathNodeType [] nodeType_;
-		string [] baseUri_;
-		bool [] isEmptyElement_;	// rotten MS spec that represents whether the original element is <foo/> or <foo></foo>.
-		string [] localName_;
-		string [] namespaceUri_;
-		string [] prefix_;
-		string [] value_;
-		string [] xmlLang_;
-		int [] namespaceNode_;
-		int [] nodeLineNumber_;
-		int [] nodeLinePosition_;
-
-		// Attribute
-		int [] ownerElement_;
-		int [] nextAttribute_;
-		string [] attrLocalName_;
-		string [] attrPrefix_;
-		string [] attrNsUri_;
-		string [] attrValue_;
-		object [] attrSchemaType_;	// for id()
-		int [] attrLineNumber_;
-		int [] attrLinePosition_;
-
-		// NamespaceNode
-		int [] nsDeclaredElement_;	// the Element that declares NS, or Root.
-		int [] nextNsNode_;		// "next" is "ancestor" or previous xmlns attr.
-		string [] nsNodeName_;		// NS prefix.
-		string [] nsNodeUri_;		// NS uri.
+		DTMXPathLinkedNode [] nodes = new DTMXPathLinkedNode [0];
+		DTMXPathAttributeNode [] attributes = new DTMXPathAttributeNode [0];
+		DTMXPathNamespaceNode [] namespaces = new DTMXPathNamespaceNode [0];
 
 		// idTable [string value] -> int nodeId
-		readonly Hashtable idTable_;
+		readonly Hashtable idTable;
 
 #endregion
 

+ 108 - 224
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs

@@ -19,12 +19,12 @@ namespace Mono.Xml.XPath
 	public class DTMXPathDocumentBuilder
 	{
 		public DTMXPathDocumentBuilder (string url)
-			: this (url, XmlSpace.None, false, 100)
+			: this (url, XmlSpace.None, false, 400)
 		{
 		}
 
 		public DTMXPathDocumentBuilder (string url, XmlSpace space)
-			: this (url, space, false, 100)
+			: this (url, space, false, 400)
 		{
 		}
 
@@ -34,135 +34,71 @@ namespace Mono.Xml.XPath
 		}
 
 		public DTMXPathDocumentBuilder (XmlReader reader)
-			: this (reader, XmlSpace.None, false, 100)
+			: this (reader, XmlSpace.None, false, 400)
 		{
 		}
 
 		public DTMXPathDocumentBuilder (XmlReader reader, XmlSpace space)
-			: this (reader, space, false, 100)
+			: this (reader, space, false, 400)
 		{
 		}
 
-		public DTMXPathDocumentBuilder (XmlReader reader, XmlSpace space, bool supportID, int defaultCapacity)
+		public DTMXPathDocumentBuilder (XmlReader reader, XmlSpace space, bool supportsID, int defaultCapacity)
 		{
 			this.xmlReader = reader;
-			if (supportID)
+			if (supportsID)
 				this.validatingReader = reader as XmlValidatingReader;
 			lineInfo = reader as IXmlLineInfo;
 			this.xmlSpace = xmlSpace;
 			this.nameTable = reader.NameTable;
-			DefaultCapacity = defaultCapacity;
+			nodeCapacity = nodeCapacity;
+			attributeCapacity = nodeCapacity * 2;
 			Compile ();
 		}
 		
-		bool supportID;
 		XmlReader xmlReader;
 		XmlValidatingReader validatingReader;
 		XmlSpace xmlSpace;
 		XmlNameTable nameTable;
 		IXmlLineInfo lineInfo;
-		int defaultCapacity = 100;
-		public int DefaultCapacity {
-			get { return defaultCapacity; }
-			set {
-				if (value < 0)
-					throw new ArgumentOutOfRangeException ();
-				defaultCapacity = value;
-			}
-		}
+		int nodeCapacity = 400;
+		int attributeCapacity = 800;
+		int nsCapacity = 10;
 
-#region Tree node info collections.
-		// Tree Node
-		int [] firstChild_ = new int [0];
-		int [] parent_ = new int [0];
-		int [] firstAttribute_ = new int [0];
-		int [] previousSibling_ = new int [0];
-		int [] nextSibling_ = new int [0];
-		int [] depth_ = new int [0];
-		int [] position_ = new int [0];
-		XPathNodeType [] nodeType_ = new XPathNodeType [0];
-		string [] baseUri_ = new string [0];
-		bool [] isEmptyElement_ = new bool [0];
-		string [] localName_ = new string [0];
-		string [] namespaceUri_ = new string [0];
-		string [] prefix_ = new string [0];
-		string [] value_ = new string [0];
-		string [] xmlLang_ = new string [0];
-		int [] namespaceNode_ = new int [0];
-		int [] nodeLineNumber_ = new int [0];
-		int [] nodeLinePosition_ = new int [0];
+		// Linked Node
+		DTMXPathLinkedNode [] nodes = new DTMXPathLinkedNode [0];
 
 		// Attribute
-		int [] ownerElement_ = new int [0];
-		int [] nextAttribute_ = new int [0];
-		string [] attrLocalName_ = new string [0];
-		string [] attrPrefix_ = new string [0];
-		string [] attrNsUri_ = new string [0];
-		string [] attrValue_ = new string [0];
-		object [] attrSchemaType_ = new object [0];
-		int [] attrLineNumber_ = new int [0];
-		int [] attrLinePosition_ = new int [0];
+		DTMXPathAttributeNode [] attributes = new DTMXPathAttributeNode [0];
 
 		// NamespaceNode
-		int [] nsDeclaredElement_ = new int [100];
-		int [] nextNsNode_ = new int [100];
-		string [] nsNodeName_ = new string [100];
-		string [] nsNodeUri_ = new string [100];
+		DTMXPathNamespaceNode [] namespaces = new DTMXPathNamespaceNode [0];
 
 		// idTable [string value] -> int nodeId
-		Hashtable idTable_;
-#endregion
+		Hashtable idTable;
 
 		int nodeIndex;
 		int attributeIndex;
 		int nsIndex;
 		bool requireFirstChildFill;
 
+		int prevSibling;
+		int position;
+		bool skipRead = false;
+
 		public DTMXPathDocument CreateDocument ()
 		{
 			return new DTMXPathDocument (nameTable,
-				firstChild_,
-				parent_,
-				firstAttribute_,
-				previousSibling_,
-				nextSibling_,
-				depth_,
-				position_,
-				nodeType_,
-				baseUri_,
-				isEmptyElement_,
-				localName_,
-				namespaceUri_,
-				prefix_,
-				value_,
-				xmlLang_,
-				namespaceNode_,
-				nodeLineNumber_,
-				nodeLinePosition_,
-
-				// Attribute
-				ownerElement_,
-				nextAttribute_,
-				attrLocalName_,
-				attrPrefix_,
-				attrNsUri_,
-				attrValue_,
-				attrSchemaType_,
-				attrLineNumber_,
-				attrLinePosition_,
-
-				// NamespaceNode
-				nsDeclaredElement_,
-				nextNsNode_,
-				nsNodeName_,
-				nsNodeUri_,
-				idTable_
+				nodes,
+				attributes,
+				namespaces,
+				idTable
 			);
 		}
 
 		public void Compile ()
 		{
-			idTable_ = new Hashtable ();
+			idTable = new Hashtable ();
 
 			// index 0 is dummy. No node (including Root) is assigned to this index
 			// So that we can easily compare index != 0 instead of index < 0.
@@ -170,12 +106,12 @@ namespace Mono.Xml.XPath
 			AddNode (0, 0, 0, 0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
 			nodeIndex++;
 			AddAttribute (0, null, null, null, null, null, 0, 0);
-			nextAttribute_ [0] = 0;
+//			attributes [0].NextAttribute = 0;
 			AddNsNode (0, null, null);
 			nsIndex++;
-			nextNsNode_ [0] = 0;
+//			nextNsNode_ [0] = 0;
 			AddNsNode (1, "xml", XmlNamespaces.XML);
-			nextNsNode_ [1] = 0;
+//			nextNsNode_ [1] = 0;
 
 			// add root.
 			AddNode (0, 0, 0, 0, -1, 0, XPathNodeType.Root, xmlReader.BaseURI, false, "", "", "", "", "", 1, 0, 0);
@@ -185,17 +121,13 @@ namespace Mono.Xml.XPath
 
 			while (!xmlReader.EOF)
 				Read ();
-			SetNodeArraysLength (nodeIndex + 1);
-			SetAttributeArraysLength (attributeIndex + 1);
-			SetNsArraysLength (nsIndex + 1);
+			SetNodeArrayLength (nodeIndex + 1);
+			SetAttributeArrayLength (attributeIndex + 1);
+			SetNsArrayLength (nsIndex + 1);
 
 			xmlReader = null;	// It is no more required.
 		}
 
-		int prevSibling;
-		int position;
-		bool skipRead = false;
-
 		public void Read ()
 		{
 			if (!skipRead)
@@ -204,10 +136,10 @@ namespace Mono.Xml.XPath
 			skipRead = false;
 			int parent = nodeIndex;
 
-			if (depth_ [nodeIndex] >= xmlReader.Depth) {	// not ">=" ? But == worked when with ArrayList...
+			if (nodes [nodeIndex].Depth >= xmlReader.Depth) {	// not ">=" ? But == worked when with ArrayList...
 				// if not, then current node is parent.
-				while (xmlReader.Depth <= depth_ [parent])
-					parent = parent_ [parent];
+				while (xmlReader.Depth <= nodes [parent].Depth)
+					parent = nodes [parent].Parent;
 			}
 
 			prevSibling = nodeIndex;
@@ -222,17 +154,17 @@ namespace Mono.Xml.XPath
 				if (requireFirstChildFill)
 					prevSibling = 0;
 				else
-					while (depth_ [prevSibling] != xmlReader.Depth)
-						prevSibling = parent_ [prevSibling];
+					while (nodes [prevSibling].Depth != xmlReader.Depth)
+						prevSibling = nodes [prevSibling].Parent;
 				if (prevSibling != 0)
-					position = position_ [prevSibling] + 1;
+					position = nodes [prevSibling].Position + 1;
 
 				nodeIndex++;
 
 				if (prevSibling != 0)
-					nextSibling_ [prevSibling] = nodeIndex;
+					nodes [prevSibling].NextSibling = nodeIndex;
 				if (requireFirstChildFill)
-					firstChild_ [parent] = nodeIndex;
+					nodes [parent].FirstChild = nodeIndex;
 				break;
 			case XmlNodeType.Whitespace:
 				if (xmlSpace == XmlSpace.Preserve)
@@ -281,7 +213,7 @@ namespace Mono.Xml.XPath
 				// this code is tricky, but after ReadString() invokation,
 				// xmlReader is moved to next node!!
 				if (value == null)
-					value_ [nodeIndex] = xmlReader.ReadString ();
+					nodes [nodeIndex].Value = xmlReader.ReadString ();
 				break;
 			case XmlNodeType.Comment:
 				value = xmlReader.Value;
@@ -309,14 +241,15 @@ namespace Mono.Xml.XPath
 						// add namespace node.
 						nsIndex++;
 
-						nextNsNode_ [nsIndex] = lastNsIndexInCurrent == 0 ? namespaceNode_ [parent] : lastNsIndexInCurrent;
+						int nextTmp = lastNsIndexInCurrent == 0 ? nodes [parent].FirstNamespace : lastNsIndexInCurrent;
 
-						if (lastNsIndexInCurrent == 0)
-							namespaceNode_ [nodeIndex] = nsIndex;
 						this.AddNsNode (nodeIndex,
 							(xmlReader.Prefix == null || xmlReader.Prefix == String.Empty) ?
 								"" : xmlReader.LocalName,
 							xmlReader.Value);
+						namespaces [nsIndex].NextNamespace = nextTmp;
+//						if (lastNsIndexInCurrent == 0)
+//							nodes [nodeIndex].FirstNamespace = nsIndex;
 						lastNsIndexInCurrent = nsIndex;
 					} else {
 						// add attribute node.
@@ -332,9 +265,9 @@ namespace Mono.Xml.XPath
 						if (firstAttributeIndex == 0)
 							firstAttributeIndex = attributeIndex;
 						else
-							nextAttribute_ [attributeIndex - 1] = attributeIndex;
+							attributes [attributeIndex - 1].NextAttribute = attributeIndex;
 						// dummy for "current" attribute.
-						nextAttribute_ [attributeIndex] = 0;
+						attributes [attributeIndex].NextAttribute = 0;
 
 						// Identity infoset
 						if (validatingReader != null) {
@@ -344,7 +277,7 @@ namespace Mono.Xml.XPath
 								dt = xsType.Datatype;
 							}
 							if (dt != null && dt.TokenizedType == XmlTokenizedType.ID)
-								idTable_.Add (xmlReader.Value, nodeIndex);
+								idTable.Add (xmlReader.Value, nodeIndex);
 						}
 					}
 				} while (xmlReader.MoveToNextAttribute ());
@@ -372,144 +305,95 @@ namespace Mono.Xml.XPath
 				requireFirstChildFill = true;
 		}
 
-		private void SetObjectArrayLength (ref object [] a, int length)
-		{
-			object [] arr = new object [length];
-			Array.Copy (a, arr, System.Math.Min (a.Length, length));
-			a = arr;
-		}
-
-		private void SetBoolArrayLength (ref bool [] a, int length)
-		{
-			bool [] bArr = new bool [length];
-			Array.Copy (a, bArr, System.Math.Min (a.Length, length));
-			a = bArr;
-		}
-
-		private void SetXPathNodeTypeArrayLength (ref XPathNodeType [] a, int length)
-		{
-			XPathNodeType [] arr = new XPathNodeType [length];
-			Array.Copy (a, arr, System.Math.Min (a.Length, length));
-			a = arr;
-		}
-
-		private void SetIntArrayLength (ref int [] a, int length)
-		{
-			int [] intArr = new int [length];
-			Array.Copy (a, intArr, System.Math.Min (a.Length, length));
-			a = intArr;
-		}
-
-		private void SetStringArrayLength (ref string [] a, int length)
-		{
-			string [] strArr = new string [length];
-			Array.Copy (a, strArr, System.Math.Min (a.Length, length));
-			a = strArr;
-		}
-
-		private void SetNodeArraysLength (int size)
+		private void SetNodeArrayLength (int size)
 		{
-			SetIntArrayLength (ref firstChild_, size);
-			SetIntArrayLength (ref parent_, size);
-			SetIntArrayLength (ref firstAttribute_, size);
-			SetIntArrayLength (ref previousSibling_, size);
-			SetIntArrayLength (ref nextSibling_, size);
-			SetIntArrayLength (ref depth_, size);
-			SetIntArrayLength (ref position_, size);
-			SetXPathNodeTypeArrayLength (ref nodeType_, size);
-			SetStringArrayLength (ref baseUri_, size);
-			SetBoolArrayLength (ref isEmptyElement_, size);
-			SetStringArrayLength (ref localName_, size);
-			SetStringArrayLength (ref namespaceUri_, size);
-			SetStringArrayLength (ref prefix_, size);
-			SetStringArrayLength (ref value_, size);
-			SetStringArrayLength (ref xmlLang_, size);
-			SetIntArrayLength (ref namespaceNode_, size);
-			SetIntArrayLength (ref nodeLineNumber_, size);
-			SetIntArrayLength (ref nodeLinePosition_, size);
+			DTMXPathLinkedNode [] newArr = new DTMXPathLinkedNode [size];
+			Array.Copy (nodes, newArr, System.Math.Min (size, nodes.Length));
+			nodes = newArr;
 		}
 
-		private void SetAttributeArraysLength (int size)
+		private void SetAttributeArrayLength (int size)
 		{
-			SetIntArrayLength (ref ownerElement_, size);
-			SetIntArrayLength (ref nextAttribute_, size);
-			SetStringArrayLength (ref attrLocalName_, size);
-			SetStringArrayLength (ref attrPrefix_, size);
-			SetStringArrayLength (ref attrNsUri_, size);
-			SetStringArrayLength (ref attrValue_, size);
-			SetObjectArrayLength (ref attrSchemaType_, size);
-			SetIntArrayLength (ref attrLineNumber_, size);
-			SetIntArrayLength (ref attrLinePosition_, size);
+			DTMXPathAttributeNode [] newArr = 
+				new DTMXPathAttributeNode [size];
+			Array.Copy (attributes, newArr, System.Math.Min (size, attributes.Length));
+			attributes = newArr;
 		}
 
-		private void SetNsArraysLength (int size)
+		private void SetNsArrayLength (int size)
 		{
-			SetIntArrayLength (ref nsDeclaredElement_, size);
-			SetIntArrayLength (ref nextNsNode_, size);
-			SetStringArrayLength (ref nsNodeName_, size);
-			SetStringArrayLength (ref nsNodeUri_, size);
+			DTMXPathNamespaceNode [] newArr =
+				new DTMXPathNamespaceNode [size];
+			Array.Copy (namespaces, newArr, System.Math.Min (size, namespaces.Length));
+			namespaces = newArr;
 		}
 
 		// Here followings are skipped: firstChild, nextSibling, 
 		public void AddNode (int parent, int firstAttribute, int attributeEnd, int previousSibling, int depth, int position, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
 		{
-			if (firstChild_.Length < nodeIndex + 1) {
-				if (firstChild_.Length >= defaultCapacity)
-					defaultCapacity *= 2;
-				SetNodeArraysLength (defaultCapacity);
+			if (nodes.Length < nodeIndex + 1) {
+//				if (nodes.Length >= nodeCapacity) {
+					nodeCapacity *= 2;
+					SetNodeArrayLength (nodeCapacity);
+//				}
 			}
 
-			firstChild_ [nodeIndex] = 0;		// dummy
-			parent_ [nodeIndex] = parent;
-			firstAttribute_ [nodeIndex] = firstAttribute;
-			previousSibling_ [nodeIndex] = previousSibling;
-			nextSibling_ [nodeIndex] = 0;	// dummy
-			depth_ [nodeIndex] = depth;
-			position_ [nodeIndex] = position;
-			nodeType_ [nodeIndex] = nodeType;
-			baseUri_ [nodeIndex] = baseUri;
-			isEmptyElement_ [nodeIndex] = isEmptyElement;
-			localName_ [nodeIndex] = localName;
-			namespaceUri_ [nodeIndex] = ns;
-			prefix_ [nodeIndex] = prefix;
-			value_ [nodeIndex] = value;
-			xmlLang_ [nodeIndex] = xmlLang;
-			namespaceNode_ [nodeIndex] = namespaceNode;
-			nodeLineNumber_ [nodeIndex] = lineNumber;
-			nodeLinePosition_ [nodeIndex] = linePosition;
+			DTMXPathLinkedNode curNode = nodes [nodeIndex];// = new DTMXPathLinkedNode ();
+			nodes [nodeIndex].FirstChild = 0;		// dummy
+			nodes [nodeIndex].Parent = parent;
+			nodes [nodeIndex].FirstAttribute = firstAttribute;
+			nodes [nodeIndex].PreviousSibling = previousSibling;
+			nodes [nodeIndex].NextSibling = 0;	// dummy
+			nodes [nodeIndex].Depth = depth;
+			nodes [nodeIndex].Position = position;
+			nodes [nodeIndex].NodeType = nodeType;
+			nodes [nodeIndex].BaseURI = baseUri;
+			nodes [nodeIndex].IsEmptyElement = isEmptyElement;
+			nodes [nodeIndex].LocalName = localName;
+			nodes [nodeIndex].NamespaceURI = ns;
+			nodes [nodeIndex].Prefix = prefix;
+			nodes [nodeIndex].Value = value;
+			nodes [nodeIndex].XmlLang = xmlLang;
+			nodes [nodeIndex].FirstNamespace = namespaceNode;
+			nodes [nodeIndex].LineNumber = lineNumber;
+			nodes [nodeIndex].LinePosition = linePosition;
 		}
 
 		// Followings are skipped: nextAttribute,
 		public void AddAttribute (int ownerElement, string localName, string ns, string prefix, string value, object schemaType, int lineNumber, int linePosition)
 		{
-			if (ownerElement_.Length < attributeIndex + 1) {
-				if (ownerElement_.Length >= defaultCapacity)
-					defaultCapacity *= 2;
-				SetAttributeArraysLength (defaultCapacity);
+			if (attributes.Length < attributeIndex + 1) {
+//				if (attributes.Length >= attributeCapacity) {
+					attributeCapacity *= 2;
+					SetAttributeArrayLength (attributeCapacity);
+//				}
 			}
 
-			ownerElement_ [attributeIndex] = ownerElement;
-			attrLocalName_ [attributeIndex] = localName;
-			attrNsUri_ [attributeIndex] = ns;
-			attrPrefix_ [attributeIndex] = prefix;
-			attrValue_ [attributeIndex] = value;
-			attrSchemaType_ [attributeIndex] = schemaType;
-			attrLineNumber_ [attributeIndex] = lineNumber;
-			attrLinePosition_ [attributeIndex] = linePosition;
+			DTMXPathAttributeNode attr = attributes [attributeIndex];// = new DTMXPathAttributeNode ();
+			attributes [attributeIndex].OwnerElement = ownerElement;
+			attributes [attributeIndex].LocalName = localName;
+			attributes [attributeIndex].NamespaceURI = ns;
+			attributes [attributeIndex].Prefix = prefix;
+			attributes [attributeIndex].Value = value;
+			attributes [attributeIndex].SchemaType = schemaType;
+			attributes [attributeIndex].LineNumber = lineNumber;
+			attributes [attributeIndex].LinePosition = linePosition;
 		}
 
 		// Followings are skipped: nextNsNode (may be next attribute in the same element, or ancestors' nsNode)
 		public void AddNsNode (int declaredElement, string name, string ns)
 		{
-			if (nsDeclaredElement_.Length < nsIndex + 1) {
-				if (nsDeclaredElement_.Length >= defaultCapacity)
-					defaultCapacity *= 2;
-				SetNsArraysLength (defaultCapacity);
+			if (namespaces.Length < nsIndex + 1) {
+//				if (namespaces.Length >= nsCapacity) {
+					nsCapacity *= 2;
+					SetNsArrayLength (nsCapacity);
+//				}
 			}
 
-			nsDeclaredElement_ [nsIndex] = declaredElement;
-			nsNodeName_ [nsIndex] = name;
-			nsNodeUri_ [nsIndex] = ns;
+			DTMXPathNamespaceNode nsNode = namespaces [nsIndex];// = new DTMXPathNamespaceNode ();
+			namespaces [nsIndex].DeclaredElement = declaredElement;
+			namespaces [nsIndex].Name = name;
+			namespaces [nsIndex].Namespace = ns;
 		}
 	}
 }

+ 106 - 186
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs

@@ -21,63 +21,17 @@ namespace Mono.Xml.XPath
 #region Copy of XPathDocument
 		public DTMXPathNavigator (DTMXPathDocument document,
 			XmlNameTable nameTable, 
-			int [] firstChild__, int [] parent__, 
-			int [] firstAttribute__, int [] previousSibling__, 
-			int [] nextSibling__, int [] depth__, 
-			int [] position__, XPathNodeType [] nodeType__,
-			string [] baseUri__, bool [] isEmptyElement__, 
-			string [] localName__, string [] namespaceUri__, 
-			string [] prefix__, string [] value__, 
-			string [] xmlLang__, int [] namespaceNode__, 
-			int [] nodeLineNumber__, int [] nodeLinePosition__, 
-			int [] ownerElement__, 
-			int [] nextAttribute__, string [] attrLocalName__, 
-			string [] attrPrefix__, string [] attrNsUri__, 
-			string [] attrValue__, object [] attrSchemaType__, 
-			int [] attrLineNumber__, int [] attrLinePosition__, 
-			int [] nsDeclaredElement__, int [] nextNsNode__, 
-			string [] nsNodeName__, string [] nsNodeUri__,
-			Hashtable idTable__)
+			DTMXPathLinkedNode [] nodes,
+			DTMXPathAttributeNode [] attributes,
+			DTMXPathNamespaceNode [] namespaces,
+			Hashtable idTable)
 		{
-			firstChild_ = firstChild__;
-			parent_ = parent__;
-			firstAttribute_ = firstAttribute__;
-			previousSibling_ = previousSibling__;
-			nextSibling_ = nextSibling__;
-			depth_ = depth__;
-			position_ = position__;
-			nodeType_ = nodeType__;
-			baseUri_ = baseUri__;
-			isEmptyElement_ = isEmptyElement__;
-			localName_ = localName__;
-			namespaceUri_ = namespaceUri__;
-			prefix_ = prefix__;
-			value_ = value__;
-			xmlLang_ = xmlLang__;
-			namespaceNode_ = namespaceNode__;
-			nodeLineNumber_ = nodeLineNumber__;
-			nodeLinePosition_ = nodeLinePosition__;
-
-			// Attribute
-			ownerElement_ = ownerElement__;
-			nextAttribute_ = nextAttribute__;
-			attrLocalName_ = attrLocalName__;
-			attrPrefix_ = attrPrefix__;
-			attrNsUri_ = attrNsUri__;
-			attrValue_ = attrValue__;
-			attrSchemaType_ = attrSchemaType__;
-			attrLineNumber_ = attrLineNumber__;
-			attrLinePosition_ = attrLinePosition__;
-
-			// NamespaceNode
-			nsDeclaredElement_ = nsDeclaredElement__;
-			nextNsNode_ = nextNsNode__;
-			nsNodeName_ = nsNodeName__;
-			nsNodeUri_ = nsNodeUri__;
-
-			idTable_ = idTable__;
-
+			this.nodes = nodes;
+			this.attributes = attributes;
+			this.namespaces = namespaces;
+			this.idTable = idTable;
 			this.nameTable = nameTable;
+
 			this.MoveToRoot ();
 			this.document = document;
 		}
@@ -85,18 +39,8 @@ namespace Mono.Xml.XPath
 		// Copy constructor including position informations.
 		public DTMXPathNavigator (DTMXPathNavigator org)
 			: this (org.document, org.nameTable,
-			org.firstChild_, org.parent_, org.firstAttribute_,
-			org.previousSibling_, org.nextSibling_, org.depth_,
-			org.position_, org.nodeType_, org.baseUri_,
-			org.isEmptyElement_, org.localName_, org.namespaceUri_,
-			org.prefix_, org.value_, org.xmlLang_,
-			org.namespaceNode_, org.nodeLineNumber_, org.nodeLinePosition_, 
-			org.ownerElement_, 
-			org.nextAttribute_, org.attrLocalName_, org.attrPrefix_, 
-			org.attrNsUri_, org.attrValue_, org.attrSchemaType_, 
-			org.attrLineNumber_, org.attrLinePosition_,
-			org.nsDeclaredElement_, org.nextNsNode_, org.nsNodeName_,
-			org.nsNodeUri_, org.idTable_)
+			org.nodes, org.attributes, org.namespaces,
+			org.idTable)
 		{
 			currentIsNode = org.currentIsNode;
 			currentIsAttr = org.currentIsAttr;
@@ -111,49 +55,16 @@ namespace Mono.Xml.XPath
 		// Created XPathDocument. This is used to identify the origin of the navigator.
 		DTMXPathDocument document;
 
-		// Tree Node
-		int [] firstChild_;
-		int [] parent_;
-		int [] firstAttribute_;
-		int [] previousSibling_;
-		int [] nextSibling_;
-		int [] depth_;
-		int [] position_;
-		XPathNodeType [] nodeType_;
-		string [] baseUri_;
-		bool [] isEmptyElement_;	// MS lamespec that represents whether the original element is <foo/> or <foo></foo>.
-		string [] localName_;
-		string [] namespaceUri_;
-		string [] prefix_;
-		string [] value_;
-		string [] xmlLang_;
-		int [] namespaceNode_;
-		int [] nodeLineNumber_;
-		int [] nodeLinePosition_;
-
-		// Attribute
-		int [] ownerElement_;
-		int [] nextAttribute_;
-		string [] attrLocalName_;
-		string [] attrPrefix_;
-		string [] attrNsUri_;
-		string [] attrValue_;
-		object [] attrSchemaType_;	// for id()
-		int [] attrLineNumber_;
-		int [] attrLinePosition_;
-
-		// NamespaceNode
-		int [] nsDeclaredElement_;	// the Element that declares NS.
-		int [] nextNsNode_;		// "next" = "ancestor".
-		string [] nsNodeName_;		// NS prefix.
-		string [] nsNodeUri_;		// NS uri.
+		DTMXPathLinkedNode [] nodes;// = new DTMXPathLinkedNode [0];
+		DTMXPathAttributeNode [] attributes;// = new DTMXPathAttributeNode [0];
+		DTMXPathNamespaceNode [] namespaces;// = new DTMXPathNamespaceNode [0];
 
 		// ID table
-		Hashtable idTable_;
+		Hashtable idTable;
 
-		// Key table (considered xsd:keyref for XPath 2.0)
-		Hashtable keyRefTable;	// [string key-name] -> idTable
-					// idTable [string value] -> int nodeId
+//		// Key table (considered xsd:keyref for XPath 2.0)
+//		Hashtable keyRefTable;	// [string key-name] -> idTable
+//					// idTable [string value] -> int nodeId
 #endregion
 
 		bool currentIsNode;
@@ -177,62 +88,73 @@ namespace Mono.Xml.XPath
 #region Properties
 
 		public override string BaseURI {
-			get { return baseUri_ [currentNode]; }
+			get { return nodes [currentNode].BaseURI; }
 		}
 
 		public override bool HasAttributes {
-			get { return currentIsNode ? firstAttribute_ [currentNode] != 0 : false; }
+			get { return currentIsNode ? nodes [currentNode].FirstAttribute != 0 : false; }
 		}
 		
 		public override bool HasChildren {
-			get { return currentIsNode ? firstChild_ [currentNode] != 0 : false; }
+			get { return currentIsNode ? nodes [currentNode].FirstChild != 0 : false; }
 		}
 
 		public override bool IsEmptyElement {
-			get { return currentIsNode ? isEmptyElement_ [currentNode] : false; }
+			get { return currentIsNode ? nodes [currentNode].IsEmptyElement : false; }
 		}
 
 		int IXmlLineInfo.LineNumber {
 			get {
-				return currentIsAttr ? attrLineNumber_ [currentAttr] :
-					nodeLineNumber_ [currentNode];
+				return currentIsAttr ? attributes [currentAttr].LineNumber :
+					nodes [currentNode].LineNumber;
 			}
 		}
 
 		int IXmlLineInfo.LinePosition {
 			get {
-				return currentIsAttr ? attrLinePosition_ [currentAttr] :
-					nodeLinePosition_ [currentNode];
+				return currentIsAttr ? attributes [currentAttr].LinePosition :
+					nodes [currentNode].LinePosition;
 			}
 		}
 
 		public override string LocalName {
-			get { return currentIsNode ? localName_ [currentNode] : currentIsAttr ? attrLocalName_ [currentAttr] : nsNodeName_ [currentNs]; }
+			get {
+				if (currentIsNode)
+					return nodes [currentNode].LocalName;
+				else if (currentIsAttr)
+					return attributes [currentAttr].LocalName;
+				else
+					return namespaces [currentNs].Name;
+			}
 		}
 
-		// It maybe scarcely used, so I decided to compute it.
+		// It maybe scarcely used, so I decided to compute it always.
 		public override string Name {
 			get {
 				string prefix;
 				string localName;
 				if (currentIsNode) {
-					prefix = prefix_ [currentNode];
-					localName = localName_ [currentNode];
+					prefix = nodes [currentNode].Prefix;
+					localName = nodes [currentNode].LocalName;
 				} else if (currentIsAttr) {
-					prefix = attrPrefix_ [currentAttr];
-					localName = attrLocalName_ [currentAttr];
+					prefix = attributes [currentAttr].Prefix;
+					localName = attributes [currentAttr].LocalName;
 				} else
-					return nsNodeName_ [currentNs];
-				return prefix != "" ? String.Format ("{0}:{1}", prefix, localName) : localName;
+					return namespaces [currentNs].Name;
+
+				if (prefix != "")
+					return prefix + ':' + localName;
+				else
+					return localName;
 			}
 		}
 
 		public override string NamespaceURI {
 			get {
 				if (currentIsNode)
-					return namespaceUri_ [currentNode];
+					return nodes [currentNode].NamespaceURI;
 				if (currentIsAttr)
-					return attrNsUri_ [currentAttr];
+					return attributes [currentAttr].NamespaceURI;
 				return String.Empty;
 			}
 		}
@@ -243,18 +165,21 @@ namespace Mono.Xml.XPath
 
 		public override XPathNodeType NodeType {
 			get {
-				return currentIsNode ? nodeType_ [currentNode] 
-				  : currentIsAttr ? XPathNodeType.Attribute
-				  : XPathNodeType.Namespace;
+				if (currentIsNode)
+					return nodes [currentNode].NodeType;
+				else if (currentIsAttr)
+					return XPathNodeType.Attribute;
+				else
+					return XPathNodeType.Namespace;
 			}
 		}
 
 		public override string Prefix {
 			get {
 				if (currentIsNode)
-					return prefix_ [currentNode];
+					return nodes [currentNode].Prefix;
 				else if (currentIsAttr)
-					return attrPrefix_ [currentAttr];
+					return attributes [currentAttr].Prefix;
 				return String.Empty;
 			}
 		}
@@ -262,31 +187,33 @@ namespace Mono.Xml.XPath
 		public override string Value {
 			get {
 				if (currentIsAttr)
-					return attrValue_ [currentAttr];
+					return attributes [currentAttr].Value;
 				else if (!currentIsNode)
-					return nsNodeUri_ [currentNs];
+					return namespaces [currentNs].Namespace;
 				
-				switch (nodeType_ [currentNode]) {
+				switch (nodes [currentNode].NodeType) {
 				case XPathNodeType.Comment:
 				case XPathNodeType.ProcessingInstruction:
 				case XPathNodeType.Text:
 				case XPathNodeType.Whitespace:
 				case XPathNodeType.SignificantWhitespace:
-					return value_ [currentNode];
+					return nodes [currentNode].Value;
 				}
+
+				// Element
 				if (valueBuilder == null)
 					valueBuilder = new StringBuilder ();
 				else
 					valueBuilder.Length = 0;
 				
-				int iter = firstChild_ [currentNode];
-				while (iter != 0 && iter < depth_.Length && depth_ [iter] > depth_ [currentNode]) {
-					switch (nodeType_ [iter]) {
+				int iter = nodes [currentNode].FirstChild;
+				while (iter != 0 && iter < nodes.Length && nodes [iter].Depth > nodes [currentNode].Depth) {
+					switch (nodes [iter].NodeType) {
 					case XPathNodeType.Comment:
 					case XPathNodeType.ProcessingInstruction:
 						break;
 					default:
-						valueBuilder.Append (value_ [iter]);
+						valueBuilder.Append (nodes [iter].Value);
 						break;
 					}
 					iter++;
@@ -297,7 +224,7 @@ namespace Mono.Xml.XPath
 		}
 
 		public override string XmlLang {
-			get { return xmlLang_ [currentNode]; }
+			get { return nodes [currentNode].XmlLang; }
 		}
 
 #endregion
@@ -340,12 +267,12 @@ namespace Mono.Xml.XPath
 
 		private int findAttribute (string localName, string namespaceURI)
 		{
-			if (currentIsNode && nodeType_ [currentNode] == XPathNodeType.Element) {
-				int cur = firstAttribute_ [currentNode];
+			if (currentIsNode && nodes [currentNode].NodeType == XPathNodeType.Element) {
+				int cur = nodes [currentNode].FirstAttribute;
 				while (cur != 0) {
-					if (attrLocalName_ [cur] == localName && attrNsUri_ [cur] == namespaceURI)
+					if (attributes [cur].LocalName == localName && attributes [cur].NamespaceURI == namespaceURI)
 						return cur;
-					cur = nextAttribute_ [cur];
+					cur = attributes [cur].NextAttribute;
 				}
 			}
 			return 0;
@@ -355,17 +282,17 @@ namespace Mono.Xml.XPath
 			string namespaceURI)
 		{
 			int attr = findAttribute (localName, namespaceURI);
-			return (attr != 0) ? attrValue_ [attr] : String.Empty;
+			return (attr != 0) ? attributes [attr].Value : String.Empty;
 		}
 
 		public override string GetNamespace (string name)
 		{
-			if (currentIsNode && nodeType_ [currentNode] == XPathNodeType.Element) {
-				int nsNode = namespaceNode_ [currentNode];
+			if (currentIsNode && nodes [currentNode].NodeType == XPathNodeType.Element) {
+				int nsNode = nodes [currentNode].FirstNamespace;
 				while (nsNode != 0) {
-					if (nsNodeName_ [nsNode] == name)
-						return nsNodeUri_ [nsNode];
-					nsNode = nextNsNode_ [nsNode];
+					if (namespaces [nsNode].Name == name)
+						return namespaces [nsNode].Namespace;
+					nsNode = namespaces [nsNode].NextNamespace;
 				}
 			}
 			return String.Empty;
@@ -386,9 +313,9 @@ namespace Mono.Xml.XPath
 			if (ComparePosition (another) != XmlNodeOrder.After)
 				return false;
 
-			int end = nextSibling_ [currentNode];
+			int end = nodes [currentNode].NextSibling;
 			if (end == 0)
-				end = nextSibling_.Length;
+				end = nodes.Length;
 			return another.currentNode < end;
 		}
 
@@ -430,14 +357,14 @@ namespace Mono.Xml.XPath
 			if (currentIsAttr)
 				return false;
 
-			int cur = previousSibling_ [currentNode];
+			int cur = nodes [currentNode].PreviousSibling;
 			if (cur == 0)
 				return false;
 
 			int next = cur;
 			while (next != 0) {
 				cur = next;
-				next = previousSibling_ [cur];
+				next = nodes [cur].PreviousSibling;
 			}
 			currentNode = cur;
 			currentIsNode = true;
@@ -449,7 +376,7 @@ namespace Mono.Xml.XPath
 			if (!currentIsNode)
 				return false;
 
-			int first = firstAttribute_ [currentNode];
+			int first = nodes [currentNode].FirstAttribute;
 			if (first == 0)
 				return false;
 
@@ -464,7 +391,7 @@ namespace Mono.Xml.XPath
 			if (!currentIsNode)
 				return false;
 
-			int first = firstChild_ [currentNode];
+			int first = nodes [currentNode].FirstChild;
 			if (first == 0)
 				return false;
 
@@ -479,21 +406,11 @@ namespace Mono.Xml.XPath
 				return false;
 
 			if (namespaceScope == XPathNamespaceScope.Local &&
-					nsDeclaredElement_ [cur] != currentNode)
+					namespaces [cur].DeclaredElement != currentNode)
 				return false;
 
-			/*
-			while (cur != 0) {
-				if (namespaceScope != XPathNamespaceScope.All
-					&& nsNodeUri_ [cur] == XmlNamespaces.XML) {
-					cur = nextNsNode_ [cur];
-					continue;
-				} else
-					break;
-			}
-			*/
 			if (namespaceScope != XPathNamespaceScope.All
-				&& nsNodeUri_ [cur] == XmlNamespaces.XML)
+				&& namespaces [cur].Namespace == XmlNamespaces.XML)
 				return false;
 
 			if (cur != 0) {
@@ -507,7 +424,7 @@ namespace Mono.Xml.XPath
 		public override bool MoveToFirstNamespace (
 			XPathNamespaceScope namespaceScope)
 		{
-			int cur = namespaceNode_ [currentNode];
+			int cur = nodes [currentNode].FirstNamespace;
 			return moveToSpecifiedNamespace (cur, namespaceScope);
 		}
 
@@ -515,9 +432,8 @@ namespace Mono.Xml.XPath
 		// XPathDocument does not support ID reference.
 		public override bool MoveToId (string id)
 		{
-//			return MoveToKeyRef ("", id);
-			if (idTable_.ContainsKey (id)) {
-				currentNode = (int) idTable_ [id];
+			if (idTable.ContainsKey (id)) {
+				currentNode = (int) idTable [id];
 				currentIsNode = true;
 				currentIsAttr = false;
 				return true;
@@ -526,6 +442,7 @@ namespace Mono.Xml.XPath
 				return false;
 		}
 
+		/*
 		// This is extension for XPath 2.0
 		public virtual bool MoveToKeyRef (string key, string value)
 		{
@@ -541,6 +458,7 @@ namespace Mono.Xml.XPath
 			currentIsAttr = false;
 			return true;
 		}
+		*/
 
 		private void moveToNamespace (int nsNode)
 		{
@@ -550,12 +468,12 @@ namespace Mono.Xml.XPath
 
 		public override bool MoveToNamespace (string name)
 		{
-			int cur = namespaceNode_ [currentNode];
+			int cur = nodes [currentNode].FirstNamespace;
 			if (cur == 0)
 				return false;
 
 			while (cur != 0) {
-				if (nsNodeName_ [cur] == name) {
+				if (namespaces [cur].Name == name) {
 					moveToNamespace (cur);
 					return true;
 				}
@@ -568,7 +486,7 @@ namespace Mono.Xml.XPath
 			if (currentIsAttr)
 				return false;
 
-			int next = nextSibling_ [currentNode];
+			int next = nodes [currentNode].NextSibling;
 			if (next == 0)
 				return false;
 			currentNode = next;
@@ -581,7 +499,7 @@ namespace Mono.Xml.XPath
 			if (!currentIsAttr)
 				return false;
 
-			int next = nextAttribute_ [currentAttr];
+			int next = attributes [currentAttr].NextAttribute;
 			if (next == 0)
 				return false;
 			currentAttr = next;
@@ -594,7 +512,7 @@ namespace Mono.Xml.XPath
 			if (currentIsAttr || currentIsNode)
 				return false;
 
-			int cur = nextNsNode_ [currentNs];
+			int cur = namespaces [currentNs].NextNamespace;
 			return moveToSpecifiedNamespace (cur, namespaceScope);
 		}
 
@@ -606,7 +524,7 @@ namespace Mono.Xml.XPath
 				return true;
 			}
 
-			int parent = parent_ [currentNode];
+			int parent = nodes [currentNode].Parent;
 			if (parent == 0)	// It is root itself.
 				return false;
 
@@ -621,7 +539,7 @@ namespace Mono.Xml.XPath
 			if (currentIsAttr)
 				return false;
 
-			int previous = previousSibling_ [currentNode];
+			int previous = nodes [currentNode].PreviousSibling;
 			if (previous == 0)
 				return false;
 			currentNode = previous;
@@ -642,19 +560,21 @@ namespace Mono.Xml.XPath
 			get {
 				StringBuilder sb = new StringBuilder ();
 
-				for (int i=0; i<this.nsDeclaredElement_.Length; i++) {
+				for (int i = 0; i < namespaces.Length; i++) {
+					DTMXPathNamespaceNode n = namespaces [i];
 					sb.AppendFormat ("{0}: {1},{2} {3}/{4}\n", i,
-						this.nsDeclaredElement_ [i], this.nextNsNode_ [i],
-						this.nsNodeName_ [i], this.nsNodeUri_ [i]);
+						n.DeclaredElement, n.NextNamespace,
+						n.Name, n.Namespace);
 				}
 
-				for (int i=0; i<this.localName_.Length; i++) {
-					sb.AppendFormat ("{0}: {1}:{2} {3} {4} {5} {6} {7}\n", new object [] {i, this.prefix_ [i], this.localName_ [i], this.namespaceUri_ [i], this.namespaceNode_ [i], this.firstAttribute_ [i], this.firstChild_ [i], this.parent_ [i]});
+				for (int i=0; i<this.nodes.Length; i++) {
+					DTMXPathLinkedNode n = nodes [i];
+					sb.AppendFormat ("{0}: {1}:{2} {3} {4} {5} {6} {7}\n", new object [] {i, n.Prefix, n.LocalName, n.NamespaceURI, n.FirstNamespace, n.FirstAttribute, n.FirstChild, n.Parent});
 				}
 
-				for (int i=0; i<this.attrLocalName_.Length; i++) {
-					sb.AppendFormat ("{0}: {1}:{2} {3} {4}\n", i, this.attrPrefix_ [i], 
-						this.attrLocalName_ [i], this.attrNsUri_ [i], this.nextAttribute_ [i]);
+				for (int i=0; i<this.attributes.Length; i++) {
+					DTMXPathAttributeNode n = attributes [i];
+					sb.AppendFormat ("{0}: {1}:{2} {3} {4}\n", i, n.Prefix, n.LocalName, n.NamespaceURI, n.NextAttribute);
 				}
 
 				return sb.ToString ();

+ 59 - 0
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs

@@ -0,0 +1,59 @@
+//
+// Mono.Xml.XPath.DTMXPathNode.cs
+//
+// Author:
+//	Atsushi Enomoto ([email protected])
+//
+// (C) 2003 Atsushi Enomoto
+//
+// These classes represent each node of DTMXPathNavigator.
+//
+
+using System;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+	public struct DTMXPathLinkedNode
+	{
+		public int FirstChild;
+		public int Parent;
+		public int PreviousSibling;
+		public int NextSibling;
+		public int FirstAttribute;
+		public int FirstNamespace;
+		public int Depth;
+		public int Position;
+		public XPathNodeType NodeType;
+		public string BaseURI;
+		public bool IsEmptyElement;
+		public string LocalName;
+		public string NamespaceURI;
+		public string Prefix;
+		public string Value;
+		public string XmlLang;
+		public int LineNumber;
+		public int LinePosition;
+	}
+
+	public struct DTMXPathAttributeNode
+	{
+		public int OwnerElement;
+		public int NextAttribute;
+		public string LocalName;
+		public string NamespaceURI;
+		public string Prefix;
+		public string Value;
+		public object SchemaType;
+		public int LineNumber;
+		public int LinePosition;
+	}
+
+	public struct DTMXPathNamespaceNode
+	{
+		public int DeclaredElement;
+		public int NextNamespace;
+		public string Name;
+		public string Namespace;
+	}
+}