Browse Source

2003-08-14 Atsushi Enomoto <[email protected]>

	* DTDValidatingReader.cs : Added SchemaType.
	  Read() Assures to return to element.
	* DTDObjectModel.cs : Removed DTDEntityDeclaration.BaseURI.
	* XmlReader.cs : ReadString() should be virtual in NET_1_1.
	* XmlTextReader.cs : 1) Depth should consider Attribute and its values.
	  Introduced insideAttribute field to support them.
	  2) ReadAttributeValue() should consider empty string.
	* XmlValidatingReader.cs :
	  Fixed several properties which premised as if it was already read.
	  Encoding and Namespaces now throws NotSupportedException for other
	  than XmlTextReader.
	  Implemented ReadTypedValue() based on IHasXmlSchemaInfo.SchemaType.

svn path=/trunk/mcs/; revision=17330
Atsushi Eno 22 years ago
parent
commit
8a41b1cdd2

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

@@ -1,3 +1,18 @@
+2003-08-14  Atsushi Enomoto <[email protected]>
+
+	* DTDValidatingReader.cs : Added SchemaType.
+	  Read() Assures to return to element.
+	* DTDObjectModel.cs : Removed DTDEntityDeclaration.BaseURI.
+	* XmlReader.cs : ReadString() should be virtual in NET_1_1.
+	* XmlTextReader.cs : 1) Depth should consider Attribute and its values.
+	  Introduced insideAttribute field to support them.
+	  2) ReadAttributeValue() should consider empty string.
+	* XmlValidatingReader.cs :
+	  Fixed several properties which premised as if it was already read.
+	  Encoding and Namespaces now throws NotSupportedException for other
+	  than XmlTextReader.
+	  Implemented ReadTypedValue() based on IHasXmlSchemaInfo.SchemaType.
+
 2003-08-10  Atsushi Enomoto <[email protected]>
 
 	* XmlInputStream.cs : Reverted CanSeek as to return false anyway.

+ 0 - 1
mcs/class/System.XML/System.Xml/DTDObjectModel.cs

@@ -747,7 +747,6 @@ namespace Mono.Xml
 		public string Name;
 		public string PublicId;
 		public string SystemId;
-		public string BaseURI;
 		public string LiteralValue;
 		public bool LoadFailed;
 

+ 12 - 1
mcs/class/System.XML/System.Xml/DTDValidatingReader.cs

@@ -8,7 +8,7 @@ using System.Xml.Schema;
 
 namespace Mono.Xml
 {
-	public class DTDValidatingReader : XmlReader, IXmlLineInfo, IHasXmlParserContext
+	public class DTDValidatingReader : XmlReader, IXmlLineInfo, IHasXmlParserContext, IHasXmlSchemaInfo
 	{
 		public DTDValidatingReader (XmlReader reader)
 			: this (reader, null)
@@ -520,6 +520,7 @@ namespace Mono.Xml
 				}
 				break;
 			}
+			MoveToElement ();
 			return true;
 		}
 
@@ -968,6 +969,16 @@ namespace Mono.Xml
 			}
 		}
 
+		public object SchemaType {
+			get {
+				if (currentElement == null)
+					return null;
+				DTDAttributeDefinition def =
+					DTD.AttListDecls [currentElement] [currentAttribute];
+				return def.Datatype;
+			}
+		}
+
 		char [] whitespaceChars = new char [] {' '};
 		private string FilterNormalization (string attrName, string rawValue)
 		{

+ 7 - 0
mcs/class/System.XML/System.Xml/XmlReader.cs

@@ -397,7 +397,14 @@ namespace System.Xml
 			Read ();
 		}
 
+#if NET_1_0
 		public abstract string ReadString ();
+#else
+		public virtual string ReadString ()
+		{
+			return ReadStringInternal ();
+		}
+#endif
 
 		internal string ReadStringInternal ()
 		{

+ 30 - 5
mcs/class/System.XML/System.Xml/XmlTextReader.cs

@@ -16,6 +16,9 @@
 //   Some thought needs to be given to performance. There's too many
 //   strings being allocated.
 //
+//   If current node is on an Attribute, Prefix might be null, and
+//   in several fields which uses XmlReader, it should be considered.
+//
 
 using System;
 using System.Collections;
@@ -99,7 +102,6 @@ namespace System.Xml
 		{
 		}
 
-		[MonoTODO("TODO as same as private XmlTextReader(TextReader, XmlNodeType, XmlParserContext)")]
 		public XmlTextReader (string xmlFragment, XmlNodeType fragType, XmlParserContext context)
 			: this (context != null ? context.BaseURI : String.Empty,
 				new StringReader (xmlFragment),
@@ -108,8 +110,6 @@ namespace System.Xml
 		{
 		}
 
-		// TODO still remains as described at head of this file,
-		// but it might not be TODO of the constructors...
 		XmlTextReader (string url, TextReader fragment, XmlNodeType fragType, XmlParserContext context)
 		{
 			InitializeContext (url, context, fragment, fragType);
@@ -132,6 +132,10 @@ namespace System.Xml
 		public override int Depth
 		{
 			get {
+				if (NodeType == XmlNodeType.Attribute)
+					return elementDepth + 1;
+				else if (insideAttribute)
+					return elementDepth + 2; // inside attribute value.
 				return elementDepth;
 			}
 		}
@@ -403,6 +407,7 @@ namespace System.Xml
 				value, // value
 				false // clearAttributes
 				);
+			insideAttribute = true;
 			attributeValuePos = 0;
 		}
 
@@ -435,6 +440,7 @@ namespace System.Xml
 					value, // value
 					false // clearAttributes
 				);
+				insideAttribute = true;
 				attributeValuePos = 0;
 			}
 
@@ -461,6 +467,7 @@ namespace System.Xml
 				orderedAttributesEnumerator = null;
 				if (isPropertySaved)
 					RestoreProperties ();
+				insideAttribute = false;
 				return true;
 			}
 
@@ -493,6 +500,7 @@ namespace System.Xml
 					value, // value
 					false // clearAttributes
 				);
+				insideAttribute = true;
 				attributeValuePos = 0;
 				return true;
 			}
@@ -505,6 +513,7 @@ namespace System.Xml
 			bool more = false;
 			isPropertySaved = false;
 			readState = ReadState.Interactive;
+			insideAttribute = false;
 
 			// It was moved from end of ReadStartTag ().
 			if (depthUp)
@@ -519,7 +528,7 @@ namespace System.Xml
 				maybeTextDecl--;
 
 			if (!more && startNodeType == XmlNodeType.Document && currentState != XmlNodeType.EndElement)
-				throw new XmlException ("Document element was not appeared.");
+				throw new XmlException ("Document element did not appear.");
 
 			return more;
 		}
@@ -543,9 +552,20 @@ namespace System.Xml
 				return false;
 
 			// If not started, then initialize attributeString when parsing is at start.
-			if (attributeValuePos == 0)
+			if (attributeValuePos == 0) {
 				attributeString =
 					value.Substring (1, value.Length - 2);
+				// If it has an empty value, this method still returns true.
+				if (attributeString.Length == 0) {
+					attributeValuePos = -1;
+					SetProperties (XmlNodeType.Text,
+						"",
+						false,
+						"",
+						false);
+					return true;
+				}
+			}
 
 			// It occurs when attribute dully consists of entity reference.
 			if (attributeValuePos == attributeString.Length)
@@ -749,6 +769,8 @@ namespace System.Xml
 		private StringBuilder valueBuilder;
 		private bool valueBuilderAvailable = false;
 
+		private bool insideAttribute;
+
 		private bool isPropertySaved;
 		private XmlNodeType saveNodeType;
 		private string saveName;
@@ -780,6 +802,7 @@ namespace System.Xml
 
 		private string attributeString;
 		private int attributeValuePos;
+
 		// This should be only referenced(used) by ReadInnerXml(). Kind of flyweight pattern.
 		private StringBuilder innerXmlBuilder;
 
@@ -904,6 +927,7 @@ namespace System.Xml
 
 				if (indexOfColon == -1) {
 					prefix = String.Empty;
+//					prefix = nodeType == XmlNodeType.Attribute ? null : String.Empty;
 					localName = name;
 				} else {
 					prefix = name.Substring (0, indexOfColon);
@@ -917,6 +941,7 @@ namespace System.Xml
 			switch (nodeType) {
 			case XmlNodeType.Attribute:
 				if (prefix == string.Empty) namespaceURI = string.Empty;
+//				if (prefix == string.Empty || prefix == null) namespaceURI = string.Empty;
 				else namespaceURI = LookupNamespace (prefix);
 				if (localName == "xmlns" && prefix == "")
 					namespaceURI = "http://www.w3.org/2000/xmlns/";

+ 103 - 65
mcs/class/System.XML/System.Xml/XmlValidatingReader.cs

@@ -21,21 +21,22 @@ namespace System.Xml {
 
 		EntityHandling entityHandling;
 		XmlReader sourceReader;
+		XmlTextReader xmlTextReader;
 		XmlReader validatingReader;
 		XmlResolver resolver;
 		ValidationType validationType;
 		XmlSchemaCollection schemas;
 		DTDValidatingReader dtdReader;
+		IHasXmlSchemaInfo schemaInfo;
 
 		#endregion // Fields
 
 		#region Constructors
 
-		[MonoTODO]
 		public XmlValidatingReader (XmlReader reader)
-			: base ()
 		{
 			this.sourceReader = reader;
+			this.xmlTextReader = reader as XmlTextReader;
 			entityHandling = EntityHandling.ExpandEntities;
 			validationType = ValidationType.Auto;
 			schemas = new XmlSchemaCollection ();
@@ -56,27 +57,29 @@ namespace System.Xml {
 		#region Properties
 
 		public override int AttributeCount {
-			[MonoTODO]
 			get { return validatingReader == null ? 0 : validatingReader.AttributeCount; }
 		}
 
 		public override string BaseURI {
-			[MonoTODO]
 			get { return validatingReader == null ? sourceReader.BaseURI : validatingReader.BaseURI; }
 		}
 
+		// This property for this class always return true.
 		public override bool CanResolveEntity {
-			get { return validatingReader == null ? false : validatingReader.CanResolveEntity; }
+			get { return true; }
 		}
 
 		public override int Depth { 
-			[MonoTODO]
 			get { return validatingReader == null ? 0 : validatingReader.Depth; }
 		}
 
 		public Encoding Encoding {
-			[MonoTODO]
-			get { throw new NotImplementedException (); }
+			get {
+				if (xmlTextReader != null)
+					return xmlTextReader.Encoding;
+				else
+					throw new NotSupportedException ("Encoding is supported only for XmlTextReader.");
+			}
 		}
 
 		public EntityHandling EntityHandling {
@@ -85,38 +88,35 @@ namespace System.Xml {
 		}
 
 		public override bool EOF { 
-			[MonoTODO]
 			get { return validatingReader == null ? false : validatingReader.EOF; }
 		}
 
 		public override bool HasValue { 
-			[MonoTODO]
 			get { return validatingReader == null ? false : validatingReader.HasValue; }
 		}
 
 		public override bool IsDefault {
-			[MonoTODO]
 			get { return validatingReader == null ? false : validatingReader.IsDefault; }
 		}
 
 		public override bool IsEmptyElement { 
-			[MonoTODO]
 			get { return validatingReader == null ? false : validatingReader.IsEmptyElement; }
 		}
 
 		public override string this [int i] { 
-			[MonoTODO]
-			get { return validatingReader [i]; }
+			get {
+				if (validatingReader == null)
+					throw new IndexOutOfRangeException ("Reader is not started.");
+				return validatingReader [i];
+			}
 		}
 
 		public override string this [string name] { 
-			[MonoTODO]
-			get { return validatingReader == null ? String.Empty : validatingReader [name]; }
+			get { return validatingReader == null ? null : validatingReader [name]; }
 		}
 
 		public override string this [string localName, string namespaceName] { 
-			[MonoTODO]
-			get { return validatingReader == null ? String.Empty : validatingReader [localName, namespaceName]; }
+			get { return validatingReader == null ? null : validatingReader [localName, namespaceName]; }
 		}
 
 		int IXmlLineInfo.LineNumber {
@@ -134,66 +134,73 @@ namespace System.Xml {
 		}
 
 		public override string LocalName { 
-			[MonoTODO]
-			get { return validatingReader == null ? String.Empty : validatingReader.LocalName; }
+			get {
+				if (validatingReader == null)
+					return String.Empty;
+				else if (Namespaces)
+					return validatingReader.LocalName;
+				else
+					return validatingReader.Name;
+			}
 		}
 
 		public override string Name {
-			[MonoTODO]
 			get { return validatingReader == null ? String.Empty : validatingReader.Name; }
 		}
 
-		[MonoTODO]
 		public bool Namespaces {
 			get {
-				XmlTextReader xtr = sourceReader as XmlTextReader;
-				if (xtr != null)
-					return xtr.Namespaces;
+				if (xmlTextReader != null)
+					return xmlTextReader.Namespaces;
 				else
-					throw new NotImplementedException ();
+					return true;
 			}
 			set {
-				XmlTextReader xtr = sourceReader as XmlTextReader;
-				if (xtr != null)
-					xtr.Namespaces = value;
+				if (ReadState != ReadState.Initial)
+					throw new InvalidOperationException ("Namespaces have to be set before reading.");
+
+				if (xmlTextReader != null)
+					xmlTextReader.Namespaces = value;
 				else
-					throw new NotImplementedException ();
+					throw new NotSupportedException ("Property 'Namespaces' is supported only for XmlTextReader.");
 			}
 		}
 
 		public override string NamespaceURI { 
-			[MonoTODO]
-			get { return validatingReader == null ? String.Empty : validatingReader.NamespaceURI; }
+			get {
+				if (validatingReader == null)
+					return String.Empty;
+				else if (Namespaces)
+					return validatingReader.NamespaceURI;
+				else
+					return String.Empty;
+			}
 		}
 
 		public override XmlNameTable NameTable { 
-			[MonoTODO]
-			get { return validatingReader == null ? null : validatingReader.NameTable; }
+			get { return validatingReader == null ? sourceReader.NameTable : validatingReader.NameTable; }
 		}
 
 		public override XmlNodeType NodeType { 
-			[MonoTODO]
 			get { return validatingReader == null ? XmlNodeType.None : validatingReader.NodeType; }
 		}
 
-		public override string Prefix { 
+		public override string Prefix {
 			[MonoTODO]
 			get { return validatingReader == null ? String.Empty : validatingReader.Prefix; }
 		}
 
 		public override char QuoteChar { 
-			[MonoTODO]
-			get { return validatingReader == null ? '"' : validatingReader.QuoteChar; }
+			get { return validatingReader == null ? sourceReader.QuoteChar : validatingReader.QuoteChar; }
 		}
 
-		[MonoTODO ("confirm which reader should be returned.")]
 		public XmlReader Reader {
 			get { return sourceReader; }
 		}
 
 		public override ReadState ReadState { 
 			[MonoTODO]
-			get { 
+			get {
 				if (validatingReader == null)
 					return ReadState.Initial;
 				return validatingReader.ReadState; 
@@ -229,12 +236,10 @@ namespace System.Xml {
 		}
 
 		public override string Value {
-			[MonoTODO]
 			get { return validatingReader == null ? String.Empty : validatingReader.Value; }
 		}
 
 		public override string XmlLang {
-			[MonoTODO]
 			get { return validatingReader == null ? String.Empty : validatingReader.XmlLang; }
 		}
 
@@ -242,12 +247,12 @@ namespace System.Xml {
 			[MonoTODO]
 			set {
 				resolver = value;
-				DTDValidatingReader dvr = validatingReader as DTDValidatingReader;
-				if (dvr != null)
-					dvr.XmlResolver = value;
 //				XmlSchemaValidatingReader xsvr = validatingReader as XmlSchemaValidatingReader;
 //				if (xsvr != null)
 //					xsvr.XmlResolver = value;
+				DTDValidatingReader dvr = validatingReader as DTDValidatingReader;
+				if (dvr != null)
+					dvr.XmlResolver = value;
 			}
 		}
 
@@ -260,28 +265,27 @@ namespace System.Xml {
 
 		#region Methods
 
-		[MonoTODO]
 		public override void Close ()
 		{
-			validatingReader.Close ();
+			if (validatingReader == null)
+				sourceReader.Close ();
+			else
+				validatingReader.Close ();
 		}
 
-		[MonoTODO]
 		public override string GetAttribute (int i)
 		{
-			return validatingReader.GetAttribute (i);
+			return this [i];
 		}
 
-		[MonoTODO]
 		public override string GetAttribute (string name)
 		{
-			return validatingReader.GetAttribute (name);
+			return this [name];
 		}
 
-		[MonoTODO]
 		public override string GetAttribute (string localName, string namespaceName)
 		{
-			return validatingReader.GetAttribute (localName, namespaceName);
+			return this [localName, namespaceName];
 		}
 
 		internal XmlParserContext GetInternalParserContext ()
@@ -296,45 +300,54 @@ namespace System.Xml {
 			return info != null ? info.HasLineInfo () : false;
 		}
 
-		[MonoTODO]
 		public override string LookupNamespace (string prefix)
 		{
-			return validatingReader.LookupNamespace (prefix);
+			if (validatingReader != null)
+				return sourceReader.LookupNamespace (prefix);
+			else
+				return validatingReader.LookupNamespace (prefix);
 		}
 
-		[MonoTODO]
 		public override void MoveToAttribute (int i)
 		{
-			validatingReader.MoveToAttribute (i);
+			if (validatingReader == null)
+				throw new IndexOutOfRangeException ("Reader is not started.");
+			else
+				validatingReader.MoveToAttribute (i);
 		}
 
-		[MonoTODO]
 		public override bool MoveToAttribute (string name)
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.MoveToAttribute (name);
 		}
 
-		[MonoTODO]
 		public override bool MoveToAttribute (string localName, string namespaceName)
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.MoveToAttribute (localName, namespaceName);
 		}
 
-		[MonoTODO]
 		public override bool MoveToElement ()
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.MoveToElement ();
 		}
 
-		[MonoTODO]
 		public override bool MoveToFirstAttribute ()
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.MoveToFirstAttribute ();
 		}
 
-		[MonoTODO]
 		public override bool MoveToNextAttribute ()
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.MoveToNextAttribute ();
 		}
 
@@ -363,36 +376,61 @@ namespace System.Xml {
 			return validatingReader.Read ();
 		}
 
-		[MonoTODO]
 		public override bool ReadAttributeValue ()
 		{
+			if (validatingReader == null)
+				return false;
 			return validatingReader.ReadAttributeValue ();
 		}
 
 #if NET_1_0
+		// LAMESPEC: MS.NET 1.0 has critical bug here.
+		// After calling these methods, validation does no more work!
 		[MonoTODO]
 		public override string ReadInnerXml ()
 		{
+			if (validatingReader == null)
+				return "";
 			return validatingReader.ReadInnerXml ();
 		}
 
 		[MonoTODO]
 		public override string ReadOuterXml ()
 		{
+			if (validatingReader == null)
+				return "";
 			return validatingReader.ReadOuterXml ();
 		}
 #endif
 
 		[MonoTODO]
+#if NET_1_0
+		public override string ReadString ()
+		{
+			return base.ReadStringInternal ();
+		}
+#else
 		public override string ReadString ()
 		{
-			return validatingReader.ReadString ();
+			return base.ReadString ();
 		}
+#endif
 
 		[MonoTODO]
 		public object ReadTypedValue ()
 		{
-			throw new NotImplementedException ();
+			if (dtdReader == null)
+				return null;
+			XmlSchemaDatatype dt = schemaInfo.SchemaType as XmlSchemaDatatype;
+			if (dt == null)
+				return null;
+			switch (NodeType) {
+			case XmlNodeType.Element:
+				return dt.ParseValue (ReadString (), NameTable, dtdReader.ParserContext.NamespaceManager);
+			case XmlNodeType.Attribute:
+				return dt.ParseValue (Value, NameTable, dtdReader.ParserContext.NamespaceManager);
+			}
+			return null;
 		}
 
 		public override void ResolveEntity ()