2
0
Эх сурвалжийг харах

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

	* XmlNodeReader.cs : several fix to get more compatible with MS.NET.

svn path=/trunk/mcs/; revision=10764
Atsushi Eno 23 жил өмнө
parent
commit
daa30f4735

+ 4 - 0
mcs/class/System.XML/System.Xml/ChangeLog

@@ -1,3 +1,7 @@
+2003-01-21  Atsushi Enomoto <[email protected]>
+
+	* XmlNodeReader.cs : several fix to get more compatible with MS.NET.
+
 2003-01-19  Atsushi Enomoto <[email protected]>
 
 	* XmlNamespaceManager.cs : fundamental change of LookupPrefix to return

+ 130 - 19
mcs/class/System.XML/System.Xml/XmlNodeReader.cs

@@ -20,17 +20,18 @@ namespace System.Xml
 	{
 		#region Constructor
 
+		XmlNode startNode;
 		XmlNode current;
 		ReadState state = ReadState.Initial;
 		int depth;
 		bool isEndElement;
 		bool isEndEntity;
-		bool nextIsEndElement;
+		bool nextIsEndElement;	// used for ReadString()
 		bool alreadyRead;
 
 		public XmlNodeReader (XmlNode node)
 		{
-			current = node;
+			startNode = node;
 			if (node.NodeType != XmlNodeType.Document
 				&& node.NodeType != XmlNodeType.DocumentFragment)
 				alreadyRead = true;
@@ -42,16 +43,26 @@ namespace System.Xml
 
 		public override int AttributeCount {
 			get {
+				if (current == null)
+					return 0;
+
 				return ((ICollection) current.Attributes).Count;
 			}
 		}
 
 		public override string BaseURI {
-			get { return current.BaseURI; }
+			get { 
+				if (current == null)
+					return String.Empty;
+				return current.BaseURI;
+			}
 		}
 
+		[MonoTODO("wait for XML resolver")]
 		public override bool CanResolveEntity {
-			get { return false; }
+			get {
+				throw new NotImplementedException ();
+			}
 		}
 
 		public override int Depth {
@@ -59,11 +70,17 @@ namespace System.Xml
 		}
 
 		public override bool EOF {
-			get { return this.ReadState == ReadState.EndOfFile; }
+			get {
+				return this.ReadState == ReadState.EndOfFile 
+				|| this.ReadState == ReadState.Error;
+			}
 		}
 
 		public override bool HasAttributes {
 			get {
+				if (current == null)
+					return false;
+
 				if (current.Attributes == null)
 					return false;
 				else
@@ -73,6 +90,9 @@ namespace System.Xml
 
 		public override bool HasValue {
 			get {
+				if (current == null)
+					return false;
+
 				if (current.NodeType == XmlNodeType.Element ||
 				    current.NodeType == XmlNodeType.EntityReference ||
 				    current.NodeType == XmlNodeType.Document ||
@@ -90,6 +110,9 @@ namespace System.Xml
 		[MonoTODO("waiting for DTD implementation")]
 		public override bool IsDefault {
 			get {
+				if (current == null)
+					return false;
+
 				if (current.NodeType != XmlNodeType.Attribute)
 					return false;
 				else
@@ -102,6 +125,9 @@ namespace System.Xml
 		[MonoTODO("test it.")]
 		public override bool IsEmptyElement {
 			get {
+				if (current == null)
+					return false;
+
 				if(current.NodeType == XmlNodeType.Element)
 					return ((XmlElement) current).IsEmpty;
 				else 
@@ -111,6 +137,9 @@ namespace System.Xml
 
 		public override string this [int i] {
 			get {
+				if (current == null)
+					return null;
+
 				if (i < 0 || i > AttributeCount)
 					throw new ArgumentOutOfRangeException ("i is out of range.");
 				
@@ -120,6 +149,9 @@ namespace System.Xml
 
 		public override string this [string name] {
 			get {
+				if (current == null)
+					return null;
+
 				string ret =  current.Attributes [name].Value;
 				
 				if (ret == null)
@@ -131,7 +163,10 @@ namespace System.Xml
 
 		public override string this [string name, string namespaceURI] {
 			get {
-				string ret =  current.Attributes [name].Value;
+				if (current == null)
+					return null;
+
+				string ret =  current.Attributes [name, namespaceURI].Value;
 				
 				if (ret == null)
 					return String.Empty;
@@ -142,6 +177,9 @@ namespace System.Xml
 
 		public override string LocalName {
 			get {
+				if (current == null)
+					return String.Empty;
+
 				if (current is XmlCharacterData)
 					return String.Empty;
 				else
@@ -150,11 +188,19 @@ namespace System.Xml
 		}
 
 		public override string Name {
-			get { return current.Name; }
+			get {
+				if (current == null)
+					return String.Empty;
+
+				return current.Name;
+			}
 		}
 
 		public override string NamespaceURI {
 			get {
+				if (current == null)
+					return String.Empty;
+
 				return current.NamespaceURI;
 			}
 		}
@@ -170,12 +216,18 @@ namespace System.Xml
 
 		public override XmlNodeType NodeType {
 			get {
+				if (current == null)
+					return XmlNodeType.None;
+
 				return isEndElement ? XmlNodeType.EndElement : current.NodeType;
 			}
 		}
 
 		public override string Prefix {
 			get { 
+				if (current == null)
+					return String.Empty;
+
 				return current.Prefix;
 			}
 		}
@@ -195,11 +247,21 @@ namespace System.Xml
 		}
 
 		public override string XmlLang {
-			get { return current.XmlLang; }
+			get {
+				if (current == null)
+					return String.Empty;
+
+				return current.XmlLang;
+			}
 		}
 
 		public override XmlSpace XmlSpace {
-			get { return current.XmlSpace; }
+			get {
+				if (current == null)
+					return XmlSpace.None;
+
+				return current.XmlSpace;
+			}
 		}
 		#endregion
 
@@ -301,21 +363,57 @@ namespace System.Xml
 		[MonoTODO("Entity handling is not supported.")]
 		public override bool Read ()
 		{
-			state = ReadState.Interactive;
+			if (EOF)
+				return false;
 
-			isEndEntity = false;
+			if (ReadState == ReadState.Initial) {
+				current = startNode;
+				state = ReadState.Interactive;
+				// when startNode is document or fragment
+				if (!alreadyRead)
+					current = startNode.FirstChild;
+				else
+					alreadyRead = false;
+				if (current == null) {
+					state = ReadState.Error;
+					return false;
+				} else
+					return true;
+			}
 
 			if (current.NodeType == XmlNodeType.Attribute)
 				current = ((XmlAttribute) current).OwnerElement;
+			isEndEntity = false;
 
-			if (nextIsEndElement) {
+			if (isEndElement) {
+				// Then go up and move to next.
+				// If no more nodes, then set EOF.
+				isEndElement = false;
+				if (current.ParentNode == null
+					|| current.ParentNode.NodeType == XmlNodeType.Document
+					|| current.ParentNode.NodeType == XmlNodeType.DocumentFragment) {
+					current = null;
+					state = ReadState.EndOfFile;
+					return false;
+				} else if (current.ParentNode.NextSibling == null) {
+					current = current.ParentNode;
+					isEndElement = true;
+					return true;
+				} else {
+					current = current.ParentNode.NextSibling;
+					return true;
+				}
+			} else if (nextIsEndElement) {
+				// nextIsEndElement is set only by ReadString.
 				nextIsEndElement = false;
 				isEndElement = true;
+				return current != null;
 			} else if (alreadyRead) {
 				alreadyRead = false;
 				return current != null;
 			}
 
+			// hmm... here may be unnecessary codes. plz check anyone ;)
 			if (!isEndElement && current.FirstChild != null) {
 				isEndElement = false;
 				current = current.FirstChild;
@@ -331,6 +429,7 @@ namespace System.Xml
 				depth--;
 				current = current.ParentNode;
 			}
+
 			return current != null;
 		}
 
@@ -350,6 +449,11 @@ namespace System.Xml
 		// Its traversal behavior is almost same as Read().
 		public override string ReadInnerXml ()
 		{
+			if (ReadState == ReadState.Initial) {
+				state = ReadState.Error;
+				return String.Empty;	// heh
+			}
+		
 			if (current.NodeType != XmlNodeType.Attribute &&
 			    current.NodeType != XmlNodeType.Element)
 				return String.Empty;
@@ -361,6 +465,9 @@ namespace System.Xml
 		// Its traversal behavior is almost same as Read().
 		public override string ReadOuterXml ()
 		{
+			if (NodeType == XmlNodeType.EndElement)
+				return String.Empty;
+
 			if (current.NodeType != XmlNodeType.Attribute &&
 			    current.NodeType != XmlNodeType.Element)
 				return String.Empty;
@@ -368,14 +475,15 @@ namespace System.Xml
 				return current.OuterXml;
 		}
 
-		[MonoTODO("test it.")]
 		public override string ReadString ()
 		{
+			if (NodeType == XmlNodeType.EndElement)
+				return String.Empty;
+
 			XmlNode original = current;
 			StringBuilder builder = new StringBuilder();
-			foreach (XmlNode child in current.ChildNodes)
-			{
-				if (child is XmlCharacterData)
+			foreach (XmlNode child in current.ChildNodes) {
+				if (child is XmlCharacterData && !(child is XmlComment))
 					builder.Append (child.Value);
 				else {
 					depth++;
@@ -384,16 +492,19 @@ namespace System.Xml
 				}
 			}
 			alreadyRead = true;
-			if (current == original)
+			if (current == original) {
 				nextIsEndElement = true;
+				Read ();
+			}
 			return builder.ToString ();
 		}
 
 		[MonoTODO]
 		public override void ResolveEntity ()
 		{
-			if (current.NodeType != XmlNodeType.EntityReference)
-				throw new InvalidOperationException ("The current node is not an Entity Reference");
+			throw new NotImplementedException ();
+//			if (current.NodeType != XmlNodeType.EntityReference)
+//				throw new InvalidOperationException ("The current node is not an Entity Reference");
 		}
 
 		[MonoTODO("test it.")]