Jelajahi Sumber

2003-05-16 Atsushi Enomoto <[email protected]>

	* changed XPathNodeType modifier to internal *protected* override.
	* XmlAttribute.cs : .ctor() now checks name validity e.g. xmlns.
	* XmlAttribute.cs, XmlElement.cs : set_Prefix checks NCName validity.
	* XmlAttributeCollection.cs : removed some incorrect TODO attributes.
	* XmlDocument.cs ; CreateAttribute(name) now auto-completes xmlns NSURI
	  when the argument is "xmlns".
	* XmlElement.cs : more compliant IsEmpty support. See also WriteTo().
	* XmlNamespaceManager.cs : added initial "xml" and "xmlns" namespaces.
	* XmlNode.cs : ser_InnerXml() throws InvalidOperationException.
	* XmlNodeReader.cs : LookupNamespace() refactory. Fixed ReadInnerXml()
	  not to set error state for non-started XmlNodeReader.
	* XmlTextReader.cs : fixed ReadAttributeValue() not to reset state.
	  BaseURI support. Fixed Initialize() to handle Attribute correctly.
	  SetProperty for attribute auto-completes xmlns NSURI.
	  Attribute and whitespace handling became more correct.
	  Don't parse external DTD if XmlResolver is null.
	* XmlTextWriter.cs : implemented WriteEntityRef().
	  WriteStartAttribute() checks if ns does not equal to that of xmlns.
	* XmlWriter.cs : trivial refactoring (WriteNode() xmldecl output).

svn path=/trunk/mcs/; revision=14613
Atsushi Eno 22 tahun lalu
induk
melakukan
d758de53b7

+ 23 - 1
mcs/class/System.XML/System.Xml/ChangeLog

@@ -1,3 +1,25 @@
+2003-05-16  Atsushi Enomoto <[email protected]>
+
+	* changed XPathNodeType modifier to internal *protected* override.
+	* XmlAttribute.cs : .ctor() now checks name validity e.g. xmlns.
+	* XmlAttribute.cs, XmlElement.cs : set_Prefix checks NCName validity.
+	* XmlAttributeCollection.cs : removed some incorrect TODO attributes.
+	* XmlDocument.cs ; CreateAttribute(name) now auto-completes xmlns NSURI
+	  when the argument is "xmlns".
+	* XmlElement.cs : more compliant IsEmpty support. See also WriteTo().
+	* XmlNamespaceManager.cs : added initial "xml" and "xmlns" namespaces.
+	* XmlNode.cs : ser_InnerXml() throws InvalidOperationException.
+	* XmlNodeReader.cs : LookupNamespace() refactory. Fixed ReadInnerXml()
+	  not to set error state for non-started XmlNodeReader.
+	* XmlTextReader.cs : fixed ReadAttributeValue() not to reset state.
+	  BaseURI support. Fixed Initialize() to handle Attribute correctly.
+	  SetProperty for attribute auto-completes xmlns NSURI.
+	  Attribute and whitespace handling became more correct.
+	  Don't parse external DTD if XmlResolver is null.
+	* XmlTextWriter.cs : implemented WriteEntityRef().
+	  WriteStartAttribute() checks if ns does not equal to that of xmlns.
+	* XmlWriter.cs : trivial refactoring (WriteNode() xmldecl output).
+
 2003-05-05  Atsushi Enomoto <[email protected]>
 
 	* XmlConvert.cs : IsInvalid() Now uses XmlConstructs.IsName(Start).
@@ -180,7 +202,7 @@
 	* XmlInputStream.cs : Changed namespace. Added XmlStreamReader(stream)
 	  and XmlStreamReader (string). Fixed XmlInputStream(url) not to use
 	  System.Net.WebClient directly.
-	* XmlParserContext.cs : baseURI don't be null.
+	* XmlParserContext.cs : baseURI never be null.
 	* XmlTextWriter.cs : use WebName for Encoding instead of HeaderName.
 	* XmlUrlResolver.cs : namespace change for XmlInputStream.
 

+ 22 - 13
mcs/class/System.XML/System.Xml/XmlAttribute.cs

@@ -28,15 +28,26 @@ namespace System.Xml
 
 		#region Constructor
 
-		[MonoTODO("need to set namespaceURI if prefix is recognized built-in ones like xmlns")]
 		protected internal XmlAttribute (
 			string prefix, 
 			string localName, 
 			string namespaceURI, 
 			XmlDocument doc) : base (doc)
 		{
-			// What to be recognized is: xml:space, xml:lang, xml:base, and
-			// xmlns and xmlns:* (when XmlDocument.Namespaces = true only)
+			// I think prefix "xml" should be checked as same, but
+			// MS.NET ignores such case.
+			if (prefix == "xmlns" || (prefix == "" && localName == "xmlns"))
+				if (namespaceURI != "http://www.w3.org/2000/xmlns/")
+					throw new ArgumentException ("Invalid attribute namespace for namespace declaration.");
+
+			// There are no means to identify the DOM is namespace-
+			// aware or not, so we can only check Name validity.
+			Exception ex;
+			if (prefix != "" && !XmlConstructs.IsValidName (prefix, out ex))
+				throw ex;
+			else if (!XmlConstructs.IsValidName (localName, out ex))
+				throw ex;
+
 			this.prefix = prefix;
 			this.localName = localName;
 			this.namespaceURI = namespaceURI;
@@ -116,7 +127,7 @@ namespace System.Xml
 			}
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.Attribute;
 			}
@@ -151,13 +162,11 @@ namespace System.Xml
 		// (5)when argument is 'xml' or 'xmlns' and namespaceURI doesn't match
 		public override string Prefix {
 			set {
-				if(IsReadOnly)
+				if (IsReadOnly)
 					throw new XmlException ("This node is readonly.");
-
-				XmlNamespaceManager nsmgr = ConstructNamespaceManager ();
-				string nsuri = nsmgr.LookupNamespace (value);
-				if(nsuri == null)
-					throw new XmlException ("Namespace URI not found for this prefix");
+				Exception ex;
+				if (!XmlConstructs.IsValidNCName (value, out ex))
+					throw ex;
 
 				prefix = value;
 			}
@@ -191,11 +200,11 @@ namespace System.Xml
 			}
 		}
 
-		internal override string XmlLang {
+		internal protected override string XmlLang {
 			get { return OwnerElement.XmlLang; }
 		}
 
-		internal override XmlSpace XmlSpace {
+		internal protected override XmlSpace XmlSpace {
 			get { return OwnerElement.XmlSpace; }
 		}
 
@@ -237,7 +246,7 @@ namespace System.Xml
 
 		#endregion
 
-		internal override XmlLinkedNode LastLinkedChild {
+		internal protected override XmlLinkedNode LastLinkedChild {
 			get { return lastChild; }
 
 			set { lastChild = value; }

+ 7 - 12
mcs/class/System.XML/System.Xml/XmlAttributeCollection.cs

@@ -37,7 +37,6 @@ namespace System.Xml
 			}
 		}
 
-		[MonoTODO]
 		[System.Runtime.CompilerServices.IndexerName ("ItemOf")]
 		public virtual XmlAttribute this [string name] {
 			get {
@@ -45,7 +44,6 @@ namespace System.Xml
 			}
 		}
 
-		[MonoTODO]
 		[System.Runtime.CompilerServices.IndexerName ("ItemOf")]
 		public virtual XmlAttribute this [int i] {
 			get {
@@ -53,7 +51,6 @@ namespace System.Xml
 			}
 		}
 
-		[MonoTODO]
 		[System.Runtime.CompilerServices.IndexerName ("ItemOf")]
 		public virtual XmlAttribute this [string localName, string namespaceURI] {
 			get {
@@ -81,7 +78,6 @@ namespace System.Xml
 				array [index + i] = Nodes [i] as XmlAttribute;
 		}
 
-		[MonoTODO] // I don't know why this method is required...
 		void ICollection.CopyTo (Array array, int index)
 		{
 			// assuming that Nodes is a correct collection.
@@ -155,21 +151,20 @@ namespace System.Xml
 
 		public virtual XmlAttribute Remove (XmlAttribute node) 
 		{
-			if(node == null || node.OwnerDocument != this.ownerElement.OwnerDocument)
-				throw new ArgumentException ("node is null or different document created this node.");
+			if (node == null)
+				throw new ArgumentException ("Specified node is null.");
+			if (node.OwnerDocument != this.ownerElement.OwnerDocument)
+				throw new ArgumentException ("Specified node is in a different document.");
 
 			XmlAttribute retAttr = null;
-			foreach(XmlAttribute attr in Nodes)
-			{
-				if(attr == node)
-				{
+			foreach (XmlAttribute attr in Nodes) {
+				if (attr == node) {
 					retAttr = attr;
 					break;
 				}
 			}
 
-			if(retAttr != null)
-			{
+			if(retAttr != null) {
 				ownerElement.OwnerDocument.onNodeRemoving (node, null);
 				base.RemoveNamedItem (retAttr.LocalName, retAttr.NamespaceURI);
 				ownerElement.OwnerDocument.onNodeRemoved (node, null);

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlCharacterData.cs

@@ -65,7 +65,7 @@ namespace System.Xml
 			}
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get { return XPathNodeType.Text; }
 		}
 

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlComment.cs

@@ -37,7 +37,7 @@ namespace System.Xml
 			get { return XmlNodeType.Comment; }
 		}
 		
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.Comment;
 			}

+ 10 - 8
mcs/class/System.XML/System.Xml/XmlDocument.cs

@@ -35,6 +35,7 @@ namespace System.Xml
 		XmlImplementation implementation;
 		bool preserveWhitespace = false;
 		WeakReference reusableXmlTextReader;
+		XmlResolver resolver;
 
 		#endregion
 
@@ -139,7 +140,7 @@ namespace System.Xml
 			get { return false; }
 		}
 
-		internal override XmlLinkedNode LastLinkedChild {
+		internal protected override XmlLinkedNode LastLinkedChild {
 			get	{
 				return lastLinkedChild;
 			}
@@ -165,7 +166,7 @@ namespace System.Xml
 			get { return XmlNodeType.Document; }
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.Root;
 			}
@@ -180,16 +181,15 @@ namespace System.Xml
 			set { preserveWhitespace = value; }
 		}
 
-		internal override string XmlLang {
+		internal protected override string XmlLang {
 			get { return String.Empty; }
 		}
 
-		[MonoTODO]
 		public virtual XmlResolver XmlResolver {
-			set { throw new NotImplementedException (); }
+			set { resolver = value; }
 		}
 
-		internal override XmlSpace XmlSpace {
+		internal protected override XmlSpace XmlSpace {
 			get {
 				return XmlSpace.None;
 			}
@@ -199,10 +199,11 @@ namespace System.Xml
 
 		#region Methods
 
-		[MonoTODO("Should BaseURI be cloned?")]
 		public override XmlNode CloneNode (bool deep)
 		{
 			XmlDocument doc = implementation.CreateDocument ();
+			doc.baseURI = baseURI;
+
 			doc.PreserveWhitespace = PreserveWhitespace;	// required?
 			if(deep)
 			{
@@ -214,7 +215,8 @@ namespace System.Xml
 
 		public XmlAttribute CreateAttribute (string name)
 		{
-			return CreateAttribute (name, String.Empty);
+			return CreateAttribute (name,
+				name == "xmlns" ? "http://www.w3.org/2000/xmlns/" : String.Empty);
 		}
 
 		public XmlAttribute CreateAttribute (string qualifiedName, string namespaceURI)

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlDocumentFragment.cs

@@ -84,7 +84,7 @@ namespace System.Xml
 
 		// It is really not a type of XmlLinkedNode,
 		//   but I copied this way from XmlElement. I looks good.
-		internal override XmlLinkedNode LastLinkedChild
+		internal protected override XmlLinkedNode LastLinkedChild
 		{
 			get { return lastLinkedChild; }
 			set { lastLinkedChild = value; }

+ 19 - 6
mcs/class/System.XML/System.Xml/XmlElement.cs

@@ -25,6 +25,7 @@ namespace System.Xml
 		private string localName;
 		private string namespaceURI;
 		private string prefix;
+		private bool isNotEmpty;
 
 		#endregion
 
@@ -104,10 +105,11 @@ namespace System.Xml
 
 		public bool IsEmpty {
 			get {
-				return (FirstChild == null);
+				return !isNotEmpty && (FirstChild == null);
 			}
 
 			set {
+				isNotEmpty = !value;
 				if(value)
 					RemoveAll();
 			}
@@ -143,7 +145,7 @@ namespace System.Xml
 			}
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.Element;
 			}
@@ -158,7 +160,15 @@ namespace System.Xml
 
 		public override string Prefix {
 			get { return prefix; }
-			set { prefix = value; }
+			set {
+				if (IsReadOnly)
+					throw new XmlException ("This node is readonly.");
+				Exception ex;
+				if (!XmlConstructs.IsValidNCName (value, out ex))
+					throw ex;
+
+				prefix = value;
+			}
 		}
 
 		#endregion
@@ -379,9 +389,12 @@ namespace System.Xml
 					w.WriteAttributeString("xmlns", attributeNode.Prefix, "http://www.w3.org/2000/xmlns/", attributeNode.NamespaceURI);
 			}
 
-			WriteContentTo(w);
-
-			w.WriteEndElement();
+			if (IsEmpty)
+				w.WriteEndElement ();
+			else {
+				WriteContentTo(w);
+				w.WriteFullEndElement();
+			}
 		}
 
 		#endregion

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlEntity.cs

@@ -58,7 +58,7 @@ namespace System.Xml
 			get { return true; } // always read-only.
 		}
 
-		internal override XmlLinkedNode LastLinkedChild {
+		internal protected override XmlLinkedNode LastLinkedChild {
 			get { return lastChild; }
 
 			set { lastChild = value; }

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlLinkedNode.cs

@@ -66,7 +66,7 @@ namespace System.Xml
 		}
 
 		// copied this way from XmlElement
-		internal override XmlLinkedNode LastLinkedChild
+		internal protected override XmlLinkedNode LastLinkedChild
 		{
 			get { return lastLinkedChild; }
 			set { lastLinkedChild = value; }

+ 3 - 0
mcs/class/System.XML/System.Xml/XmlNamespaceManager.cs

@@ -33,6 +33,9 @@ namespace System.Xml
 			nameTable.Add ("http://www.w3.org/XML/1998/namespace");
 
 			PushScope ();
+			currentScope.Namespaces = new Hashtable ();
+			currentScope.Namespaces.Add ("xml", "http://www.w3.org/XML/1998/namespace");
+			currentScope.Namespaces.Add ("xmlns", "http://www.w3.org/2000/xmlns/");
 		}
 
 		#endregion

+ 8 - 14
mcs/class/System.XML/System.Xml/XmlNode.cs

@@ -45,14 +45,7 @@ namespace System.Xml
 			get {
 				// Isn't it conformant to W3C XML Base Recommendation?
 				// As far as I tested, there are not...
-				string result = (ParentNode != null) ? ParentNode.BaseURI : OwnerDocument.BaseURI;
-				try {
-					Uri test = new Uri(result);
-				}
-				catch {
-					result = "file://" + result;
-				}
-				return result;
+				return (ParentNode != null) ? ParentNode.BaseURI : OwnerDocument.BaseURI;
 			}
 		}
 
@@ -100,7 +93,6 @@ namespace System.Xml
 			}
 		}
 
-		[MonoTODO("Setter.")]
 		public virtual string InnerXml {
 			get {
 				StringWriter sw = new StringWriter ();
@@ -111,7 +103,9 @@ namespace System.Xml
 				return sw.GetStringBuilder ().ToString ();
 			}
 
-			set { throw new NotImplementedException (); }
+			set {
+				throw new InvalidOperationException ("This node is readonly or doesn't have any children.");
+			}
 		}
 
 		public virtual bool IsReadOnly {
@@ -151,7 +145,7 @@ namespace System.Xml
 			get { return LastLinkedChild; }
 		}
 
-		internal virtual XmlLinkedNode LastLinkedChild {
+		internal protected virtual XmlLinkedNode LastLinkedChild {
 			get { return null; }
 			set { }
 		}
@@ -170,7 +164,7 @@ namespace System.Xml
 
 		public abstract XmlNodeType NodeType { get;	}
 
-		internal virtual XPathNodeType XPathNodeType {
+		internal protected virtual XPathNodeType XPathNodeType {
 			get {
 				return (XPathNodeType) (-1);
 			}
@@ -209,7 +203,7 @@ namespace System.Xml
 			set { throw new InvalidOperationException ("This node does not have a value"); }
 		}
 
-		internal virtual string XmlLang {
+		internal protected virtual string XmlLang {
 			get {
 				if(Attributes != null)
 					foreach(XmlAttribute attr in Attributes)
@@ -219,7 +213,7 @@ namespace System.Xml
 			}
 		}
 
-		internal virtual XmlSpace XmlSpace {
+		internal protected virtual XmlSpace XmlSpace {
 			get {
 				if(Attributes != null) {
 					foreach(XmlAttribute attr in Attributes) {

+ 25 - 15
mcs/class/System.XML/System.Xml/XmlNodeReader.cs

@@ -27,6 +27,7 @@ namespace System.Xml
 		bool nextIsEndElement;	// used for ReadString()
 		bool alreadyRead;
 		StringBuilder valueBuilder = new StringBuilder ();
+		XmlNamespaceManager defaultNsmgr;
 
 		private XmlNode ownerElement {
 			get {
@@ -42,6 +43,7 @@ namespace System.Xml
 			if (node.NodeType != XmlNodeType.Document
 				&& node.NodeType != XmlNodeType.DocumentFragment)
 				alreadyRead = true;
+			defaultNsmgr = new XmlNamespaceManager (this.NameTable);
 		}
 		
 		#endregion
@@ -352,11 +354,31 @@ namespace System.Xml
 			return this [name, namespaceURI];
 		}
 
-		// FIXME: Its performance is not good.
 		public override string LookupNamespace (string prefix)
 		{
-			XmlNamespaceManager nsmgr = current.ConstructNamespaceManager();
-			return nsmgr.LookupNamespace (prefix);
+			if (current == null)
+				return null;
+
+			XmlAttribute curAttr = current as XmlAttribute;
+			XmlNode target = curAttr != null ? curAttr.OwnerElement : current;
+
+			if (prefix == "") {
+				do {
+					XmlAttribute attr = target.Attributes ["xmlns"];
+					if (attr != null)
+						return attr.Value;
+					target = current.ParentNode;
+				} while (target.NodeType != XmlNodeType.Document);
+			} else {
+				string name = "xmlns:" + prefix;
+				do {
+					XmlAttribute attr = target.Attributes [name];
+					if (attr != null)
+						return attr.Value;
+					target = current.ParentNode;
+				} while (target.NodeType != XmlNodeType.Document);
+			}
+			return defaultNsmgr.LookupNamespace (prefix);
 		}
 
 		public override void MoveToAttribute (int attributeIndex)
@@ -557,21 +579,9 @@ namespace System.Xml
 				return false;
 		}
 
-		[MonoTODO("Need to move to next content.")]
 		// Its traversal behavior is almost same as Read().
 		public override string ReadInnerXml ()
 		{
-			if (ReadState == ReadState.Initial) {
-				state = ReadState.Error;
-				return String.Empty;
-			}
-/*
-			if (current.NodeType != XmlNodeType.Attribute &&
-			    current.NodeType != XmlNodeType.Element)
-				return String.Empty;
-			else
-				return current.InnerXml;
-*/
 			XmlNode initial = current;
 			// Almost copied from XmlTextReader.
 			switch (NodeType) {

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlNotation.cs

@@ -49,7 +49,7 @@ namespace System.Xml
 			get { return true; } // Notation nodes are always read-only
 		}
 
-		internal override XmlLinkedNode LastLinkedChild {
+		internal protected override XmlLinkedNode LastLinkedChild {
 			get { return lastChild; }
 
 			set { lastChild = value; }

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlProcessingInstruction.cs

@@ -60,7 +60,7 @@ namespace System.Xml
 			get { return XmlNodeType.ProcessingInstruction; }
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.ProcessingInstruction;
 			}

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlSignificantWhitespace.cs

@@ -33,7 +33,7 @@ namespace System.Xml
 			get { return XmlNodeType.SignificantWhitespace; }
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.SignificantWhitespace;
 			}

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlText.cs

@@ -37,7 +37,7 @@ namespace System.Xml
 			get { return XmlNodeType.Text; }
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get {
 				return XPathNodeType.Text;
 			}

+ 41 - 17
mcs/class/System.XML/System.Xml/XmlTextReader.cs

@@ -515,11 +515,11 @@ namespace System.Xml
 			// attributeString which may be used next time.
 
 			if (attributeValuePos < 0) {
-				SetProperties (XmlNodeType.None,
-					String.Empty,
-					false,
-					String.Empty,
-					false);
+//				SetProperties (XmlNodeType.None,
+//					String.Empty,
+//					false,
+//					String.Empty,
+//					false);
 				return false;
 			}
 
@@ -699,13 +699,19 @@ namespace System.Xml
 					String.Empty,
 					XmlSpace.None);
 			}
-			if (url != null && url != String.Empty)
-				parserContext.BaseURI = url;
+
+			if (url != null && url != String.Empty) {
+				string path = Path.GetFullPath (".");
+				UriBuilder ub = new UriBuilder (path);
+				ub.Scheme = "file";
+				parserContext.BaseURI = new Uri (ub.Uri, url).ToString ();
+			}
+
 			Init ();
 
 			switch (fragType) {
 			case XmlNodeType.Attribute:
-				value = "''";
+				value = fragment.ReadToEnd ();
 				break;
 			case XmlNodeType.Element:
 				allowMultipleRoot = true;
@@ -868,7 +874,18 @@ namespace System.Xml
 				localName = name;
 			}
 
-			namespaceURI = LookupNamespace (prefix);
+			switch (nodeType) {
+			case XmlNodeType.Attribute:
+			case XmlNodeType.Element:
+			case XmlNodeType.EndElement:
+				namespaceURI = LookupNamespace (prefix);
+				if (localName == "xmlns" && prefix == "")
+					namespaceURI = "http://www.w3.org/2000/xmlns/";
+				break;
+			default:
+				namespaceURI = "";
+				break;
+			}
 		}
 
 		private void SaveProperties ()
@@ -1021,12 +1038,12 @@ namespace System.Xml
 				throw ReaderError("document has terminated, cannot open new element");
 
 			haveEnteredDocument = true;
-			SkipWhitespace ();
 
 			bool isEmptyElement = false;
 
 			ClearAttributes ();
 
+			SkipWhitespace ();
 			if (XmlConstructs.IsNameStart (PeekChar ()))
 				ReadAttributes (false);
 
@@ -1269,13 +1286,15 @@ namespace System.Xml
 		private void ReadAttributes (bool allowPIEnd)
 		{
 			int peekChar = -1;
+			bool requireWhitespace = false;
 			do {
+				if (!SkipWhitespace () && requireWhitespace)
+					throw new XmlException ("Unexpected token. Name is required here.");
 				string name = ReadName ();
 				SkipWhitespace ();
 				Expect ('=');
 				SkipWhitespace ();
 				string value = ReadAttribute ();
-				SkipWhitespace ();
 
 				if (name == "xmlns")
 					parserContext.NamespaceManager.AddNamespace (String.Empty, UnescapeAttributeValue (value));
@@ -1283,6 +1302,11 @@ namespace System.Xml
 					parserContext.NamespaceManager.AddNamespace (name.Substring (6), UnescapeAttributeValue (value));
 
 				AddAttribute (name, value);
+
+				if (XmlConstructs.IsSpace (PeekChar ()))
+					SkipWhitespace ();
+				else
+					requireWhitespace = true;
 				peekChar = PeekChar ();
 				if (peekChar == '?' && allowPIEnd)
 					break;
@@ -1330,11 +1354,11 @@ namespace System.Xml
 		private void ReadProcessingInstruction ()
 		{
 			string target = ReadName ();
-			SkipWhitespace ();
 			if (target == "xml") {
 				ReadXmlDeclaration ();
 				return;
 			}
+			SkipWhitespace ();
 
 			valueLength = 0;
 
@@ -1363,8 +1387,7 @@ namespace System.Xml
 		{
 			ClearAttributes ();
 
-			if (XmlConstructs.IsNameStart (PeekChar ()))
-				ReadAttributes (true);
+			ReadAttributes (true);	// They must have "version."
 			Expect ("?>");
 
 			SetProperties (
@@ -1529,7 +1552,7 @@ namespace System.Xml
 					this.ReaderError ("INCLUDE section is not ended correctly.");
 				currentInput = original;
 			}
-			if (systemId != String.Empty) {
+			if (systemId != String.Empty && resolver != null) {
 				pushParserInput (systemId);
 				do {
 					this.CompileDTDSubset ();
@@ -1885,7 +1908,6 @@ namespace System.Xml
 				switch (skip ? PeekChar () : ReadChar ()) {
 				case -1:
 					throw ReaderError ("Unexpected IGNORE section end.");
-					break;
 				case '<':
 					if (ReadChar () == '!' && ReadChar () == '[')
 						dtdIgnoreSect++;
@@ -2559,11 +2581,13 @@ namespace System.Xml
 		}
 
 		// Does not consume the first non-whitespace character.
-		private void SkipWhitespace ()
+		private bool SkipWhitespace ()
 		{
 			//FIXME: Should not skip if whitespaceHandling == WhiteSpaceHandling.None
+			bool skipped = XmlConstructs.IsSpace (PeekChar ());
 			while (XmlConstructs.IsSpace (PeekChar ()))
 				ReadChar ();
+			return skipped;
 		}
 
 		private bool ReadWhitespace ()

+ 5 - 12
mcs/class/System.XML/System.Xml/XmlTextWriter.cs

@@ -442,10 +442,11 @@ namespace System.Xml
 			namespaceManager.PopScope();
 		}
 
-		[MonoTODO]
 		public override void WriteEntityRef (string name)
 		{
-			throw new NotImplementedException ();
+			WriteRaw ("&");
+			WriteStringInternal (name, true);
+			WriteRaw (";");
 		}
 
 		public override void WriteFullEndElement ()
@@ -499,9 +500,9 @@ namespace System.Xml
 			string prefix = namespaceManager.LookupPrefix (ns);
 			w.Write ("{0}:{1}", prefix, localName);
 		}
+
 		public override void WriteRaw (string data)
 		{
-//			WriteRawInternal (data);
 			WriteStringInternal (data, false);
 		}
 
@@ -511,14 +512,6 @@ namespace System.Xml
 			WriteStringInternal (new string (buffer, index, count), false);
 		}
 
-		private void WriteRawInternal (string text)
-		{
-			if (text == null)
-				return;
-
-			w.Write (text);
-		}
-
 		public override void WriteStartAttribute (string prefix, string localName, string ns)
 		{
 			if ((prefix == "xml") && (localName == "lang"))
@@ -548,7 +541,7 @@ namespace System.Xml
 			{
 				string existingPrefix = namespaceManager.LookupPrefix (ns);
 
-				if (prefix == String.Empty)
+				if (prefix == String.Empty && ns != "http://www.w3.org/2000/xmlns/")
 					prefix = (existingPrefix == null) ?
 						String.Empty : existingPrefix;
 			}

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlWhitespace.cs

@@ -33,7 +33,7 @@ namespace System.Xml
 			get { return XmlNodeType.Whitespace; }
 		}
 
-		internal override XPathNodeType XPathNodeType {
+		internal protected override XPathNodeType XPathNodeType {
 			get { return XPathNodeType.Whitespace; }
 		}
 

+ 1 - 11
mcs/class/System.XML/System.Xml/XmlWriter.cs

@@ -52,16 +52,6 @@ namespace System.Xml
 
 			switch (reader.NodeType) {
 			case XmlNodeType.XmlDeclaration:
-				string val = reader ["version"];
-				if (val != String.Empty)
-					WriteAttributeString ("version", val);
-				val = reader ["encoding"];
-				if (val != String.Empty)
-					WriteAttributeString ("encoding", val);
-				val = reader ["standalone"];
-				if(val != String.Empty)
-					WriteAttributeString ("standalone", val);
-				break;
 			case XmlNodeType.Element:
 				if (reader.MoveToFirstAttribute ())
 					goto case XmlNodeType.Attribute;
@@ -185,7 +175,7 @@ namespace System.Xml
 					do {
 						WriteNode (reader, defattr);
 					} while (depth < reader.Depth);
-					WriteEndElement ();
+					WriteFullEndElement ();
 				}
 				break;
 			// In case of XmlAttribute, don't proceed reader.