Browse Source

2004-02-04 Atsushi Enomoto <[email protected]>

	* DTDObjectModel.cs : Never expand entity on ScanEntityValue().
	* DTDValidatingReader.cs : XmlDeclaration node requires attributes
	  to be movable.
	* XmlAttribute.cs,
	  XmlDocument.cs,
	  XmlDocumentFragment.cs,
	  XmlElement.cs,
	  XmlEntity.cs,
	  XmlLinkedNode.cs,
	  XmlNode.cs,
	  XmlNotation.cs :
	  Added namespace checking flag (required for such xml readers
	  that holds Namespaces=false). Now only XmlNode holds LastLinkedNode.
	* XmlDocumentType.cs,
	  XmlEntity.cs,
	  XmlEntityReference.cs : The children of Entity and EntityReference
	  became correct. They now holds parsed nodes, but it is only when
	  they are appended to the document.
	* XmlNode.cs : Modified insertBeforeIntern() to InsertBefore() with
	  boolean checkNodeType argument.  This method also tries to create
	  Entity's and EntityReference's child nodes.  Also added internal
	  RemoveChild() with boolean checkNodeType argument.
	* XmlNodeReader.cs : Quick hack for ResolveEntity() that became
	  broken with these changes. use InnerXml as input to entityReader.
	* XmlTextReader.cs : XmlDeclaration's value LocalName should be the
	  same as Name.  The names of DTD's pseudo attributes should be empty.
	  Fixed DTD node's Depth (was regarded as attribute value's depth).

svn path=/trunk/mcs/; revision=22767
Atsushi Eno 22 years ago
parent
commit
fdf21b83be

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

@@ -1,3 +1,33 @@
+2004-02-04  Atsushi Enomoto <[email protected]>
+
+	* DTDObjectModel.cs : Never expand entity on ScanEntityValue().
+	* DTDValidatingReader.cs : XmlDeclaration node requires attributes
+	  to be movable.
+	* XmlAttribute.cs,
+	  XmlDocument.cs,
+	  XmlDocumentFragment.cs,
+	  XmlElement.cs,
+	  XmlEntity.cs,
+	  XmlLinkedNode.cs,
+	  XmlNode.cs,
+	  XmlNotation.cs : 
+	  Added namespace checking flag (required for such xml readers
+	  that holds Namespaces=false). Now only XmlNode holds LastLinkedNode.
+	* XmlDocumentType.cs,
+	  XmlEntity.cs,
+	  XmlEntityReference.cs : The children of Entity and EntityReference
+	  became correct. They now holds parsed nodes, but it is only when
+	  they are appended to the document.
+	* XmlNode.cs : Modified insertBeforeIntern() to InsertBefore() with
+	  boolean checkNodeType argument.  This method also tries to create
+	  Entity's and EntityReference's child nodes.  Also added internal
+	  RemoveChild() with boolean checkNodeType argument.
+	* XmlNodeReader.cs : Quick hack for ResolveEntity() that became 
+	  broken with these changes. use InnerXml as input to entityReader.
+	* XmlTextReader.cs : XmlDeclaration's value LocalName should be the
+	  same as Name.  The names of DTD's pseudo attributes should be empty.
+	  Fixed DTD node's Depth (was regarded as attribute value's depth).
+
 2004-02-03  Atsushi Enomoto <[email protected]>
 
 	* XmlTextReader.cs, DTDReader.cs : fixity fix ;)

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

@@ -925,7 +925,6 @@ namespace Mono.Xml
 				Root.AddError (new XmlSchemaException ("Invalid reference character '&' is specified.",
 					this.LineNumber, this.LinePosition, null, this.BaseURI, null));
 			scanned = true;
-			entityValue = value;
 			recursed = false;
 		}
 	}

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

@@ -377,6 +377,7 @@ namespace Mono.Xml
 			case XmlNodeType.XmlDeclaration:
 				if (GetAttribute ("standalone") == "yes")
 					isStandalone = true;
+				ValidateAttributes (null, false);
 				break;
 
 			case XmlNodeType.DocumentType:

+ 3 - 10
mcs/class/System.XML/System.Xml/XmlAttribute.cs

@@ -19,7 +19,6 @@ namespace System.Xml
 	{
 		#region Fields
 
-		private XmlLinkedNode lastChild;
 		private string localName;
 		private string namespaceURI;
 		private string prefix;
@@ -34,7 +33,7 @@ namespace System.Xml
 			string prefix, 
 			string localName, 
 			string namespaceURI,
-			XmlDocument doc) : this (prefix, localName, namespaceURI, doc, false)
+			XmlDocument doc) : this (prefix, localName, namespaceURI, doc, false, true)
 		{
 		}
 
@@ -43,7 +42,7 @@ namespace System.Xml
 			string localName, 
 			string namespaceURI,
 			XmlDocument doc,
-			bool atomizedNames) : base (doc)
+			bool atomizedNames, bool checkNamespace) : base (doc)
 		{
 			if (prefix == null)
 				prefix = String.Empty;
@@ -230,7 +229,7 @@ namespace System.Xml
 		public override XmlNode CloneNode (bool deep)
 		{
 			XmlNode node = new XmlAttribute (prefix, localName, namespaceURI,
-							 OwnerDocument, true);
+							 OwnerDocument, true, false);
 			if (deep) {
 				foreach (XmlNode child in this.ChildNodes)
 					node.AppendChild (child.CloneNode (deep));
@@ -263,11 +262,5 @@ namespace System.Xml
 		}
 
 		#endregion
-
-		internal override XmlLinkedNode LastLinkedChild {
-			get { return lastChild; }
-
-			set { lastChild = value; }
-		}
 	}
 }

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

@@ -29,7 +29,6 @@ namespace System.Xml
 	{
 		#region Fields
 
-		XmlLinkedNode lastLinkedChild;
 		XmlNameTable nameTable;
 		string baseURI = String.Empty;
 		XmlImplementation implementation;
@@ -141,16 +140,6 @@ namespace System.Xml
 			}
 		}
 
-		internal override XmlLinkedNode LastLinkedChild {
-			get	{
-				return lastLinkedChild;
-			}
-
-			set {
-				lastLinkedChild = value;
-			}
-		}
-		
 		public override string LocalName {
 			get { return "#document"; }
 		}
@@ -263,7 +252,7 @@ namespace System.Xml
 			if ((localName == null) || (localName == String.Empty))
 				throw new ArgumentException ("The attribute local name cannot be empty.");
 
-			return new XmlAttribute (prefix, localName, namespaceURI, this, false);
+			return new XmlAttribute (prefix, localName, namespaceURI, this, false, true);
 		}
 
 		public virtual XmlCDataSection CreateCDataSection (string data)

+ 0 - 13
mcs/class/System.XML/System.Xml/XmlDocumentFragment.cs

@@ -16,11 +16,6 @@ namespace System.Xml
 {
 	public class XmlDocumentFragment : XmlNode
 	{
-		#region Fields
-
-		private XmlLinkedNode lastLinkedChild;
-
-		#endregion
 
 		#region Constructor
 
@@ -84,14 +79,6 @@ namespace System.Xml
 			get { return null; } // it's always null here.
 		}
 
-		// It is really not a type of XmlLinkedNode,
-		//   but I copied this way from XmlElement. It looks good.
-		internal override XmlLinkedNode LastLinkedChild
-		{
-			get { return lastLinkedChild; }
-			set { lastLinkedChild = value; }
-		}
-
 		internal override XPathNodeType XPathNodeType
 		{
 			get { return XPathNodeType.Root; }

+ 0 - 8
mcs/class/System.XML/System.Xml/XmlDocumentType.cs

@@ -16,10 +16,6 @@ namespace System.Xml
 	public class XmlDocumentType  : XmlLinkedNode
 	{
 		// Fields
-//		string name;            // name of the document type
-//		string publicId;        // public identifier on the DOCTYPE
-//		string systemId;        // system identifier on the DOCTYPE
-//		string internalSubset;  // value of the DTD internal subset
 		internal XmlNamedNodeMap entities;
 		internal XmlNamedNodeMap notations;
 		DTDObjectModel dtd;
@@ -53,8 +49,6 @@ namespace System.Xml
 			foreach (DTDEntityDeclaration decl in DTD.EntityDecls.Values) {
 				XmlNode n = new XmlEntity (decl.Name, decl.NotationName,
 					decl.PublicId, decl.SystemId, OwnerDocument);
-				// FIXME: Value is more complex, similar to Attribute.
-				n.insertBeforeIntern (OwnerDocument.CreateTextNode (decl.LiteralEntityValue), null);
 				entities.Nodes.Add (n);
 			}
 			foreach (DTDNotationDeclaration decl in DTD.NotationDecls.Values) {
@@ -118,8 +112,6 @@ namespace System.Xml
 		public override XmlNode CloneNode (bool deep)
 		{
 			// deep is ignored
-//			return new XmlDocumentType (Name, PublicId, SystemId,
-//						    InternalSubset, OwnerDocument);
 			return new XmlDocumentType (dtd, OwnerDocument);
 		}
 		

+ 2 - 2
mcs/class/System.XML/System.Xml/XmlElement.cs

@@ -113,7 +113,7 @@ namespace System.Xml
 				while (FirstChild != null)
 					this.RemoveChild (FirstChild);
 
-				// I hope there are any well-performance logic...
+				// TODO: Can we optimize it?
 				XmlNameTable nt = this.OwnerDocument.NameTable;
 				XmlNamespaceManager nsmgr = this.ConstructNamespaceManager ();
 				XmlParserContext ctx = new XmlParserContext (OwnerDocument.NameTable, nsmgr,
@@ -346,7 +346,7 @@ namespace System.Xml
 		public virtual XmlAttribute SetAttributeNode (string localName, string namespaceURI)
 		{
 			XmlDocument xmlDoc = this.OwnerDocument;
-			XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc, false);
+			XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc, false, true);
 			return this.attributes.Append (xmlAttribute);
 		}
 

+ 33 - 8
mcs/class/System.XML/System.Xml/XmlEntity.cs

@@ -3,9 +3,12 @@
 //
 // Author:
 // 	Duncan Mak  ([email protected])
+//	Atsushi Enomoto  ([email protected])
 //
 // (C) Ximian, Inc.
+// (C) 2004 Novell Inc.
 //
+using Mono.Xml;
 
 namespace System.Xml
 {
@@ -49,7 +52,7 @@ namespace System.Xml
 		}
 
 		public override string InnerXml {
-			get { return String.Empty; }
+			get { return base.InnerXml; }
 			set { throw new InvalidOperationException ("This operation is not supported."); }
 		}
 
@@ -57,12 +60,6 @@ namespace System.Xml
 			get { return true; } // always read-only.
 		}
 
-		internal override XmlLinkedNode LastLinkedChild {
-			get { return lastChild; }
-
-			set { lastChild = value; }
-		}
-
 		public override string LocalName {
 			get { return name; }
 		}
@@ -123,7 +120,35 @@ namespace System.Xml
 		{
 			// No effect.
 		}
-
+
+		internal void SetEntityContent ()
+		{
+			if (FirstChild != null)
+				return;
+
+			XmlDocumentType doctype = OwnerDocument.DocumentType;
+
+			if (doctype == null)
+				return;
+
+			DTDEntityDeclaration decl = doctype.DTD.EntityDecls [name];
+			if (decl == null)
+				return;
+
+			XmlNameTable nt = this.OwnerDocument.NameTable;
+			XmlNamespaceManager nsmgr = this.ConstructNamespaceManager ();
+			XmlParserContext ctx = new XmlParserContext (OwnerDocument.NameTable, nsmgr,
+				doctype != null ? doctype.DTD : null,
+				BaseURI, XmlLang, XmlSpace, null);
+			XmlTextReader xmlReader = new XmlTextReader (decl.EntityValue, XmlNodeType.Element, ctx);
+			xmlReader.XmlResolver = OwnerDocument.Resolver;
+
+			do {
+				XmlNode n = OwnerDocument.ReadNode (xmlReader);
+				if(n == null) break;
+				InsertBefore (n, null, false);
+			} while (true);
+		}
 		#endregion
 	}
 }

+ 24 - 10
mcs/class/System.XML/System.Xml/XmlEntityReference.cs

@@ -2,11 +2,13 @@
 // System.Xml.XmlEntityReference.cs
 // Author:
 //	Duncan Mak  ([email protected])
+//	Atsushi Enomoto  ([email protected])
 //
 // (C) Ximian, Inc. http://www.ximian.com
+// (C) 2004 Novell inc.
 //
-
 using System;
+using Mono.Xml;
 
 namespace System.Xml
 {
@@ -19,14 +21,6 @@ namespace System.Xml
 			: base (doc)
 		{
 			entityName = doc.NameTable.Add (name);
-			// fetch entity reference value from document dtd
-			// and add it as a text child to entity reference
-			string entityValueText = (doc.DocumentType != null) ? doc.DocumentType.DTD.ResolveEntity (name) : null;
-			if (entityValueText != null && entityValueText.Length > 0) {
-				XmlNode entityValueNode = new XmlText (entityValueText,doc);
-				//can't just AppendChild because EntityReference node is always read-only
-				this.insertBeforeIntern (entityValueNode,null);
-			}
 		}
 
 		// Properties
@@ -69,7 +63,8 @@ namespace System.Xml
 
 		public override void WriteContentTo (XmlWriter w)
 		{
-			// nothing to write for this object.
+			foreach (XmlNode n in ChildNodes)
+				n.WriteTo (w);
 		}
 
 		public override void WriteTo (XmlWriter w)
@@ -78,5 +73,24 @@ namespace System.Xml
 			w.WriteName(Name);
 			w.WriteRaw(";");
 		}
+
+		internal void SetReferencedEntityContent ()
+		{
+			if (FirstChild != null)
+				return;
+
+			XmlDocumentType doctype = OwnerDocument.DocumentType;
+			if (doctype == null)
+				return;
+
+			XmlEntity ent = doctype.Entities.GetNamedItem (Name) as XmlEntity;
+			if (ent == null)
+				InsertBefore (OwnerDocument.CreateTextNode (String.Empty), null, false);
+			else {
+				ent.SetEntityContent ();
+				for (int i = 0; i < ent.ChildNodes.Count; i++)
+					InsertBefore (ent.ChildNodes [i].CloneNode (true), null, false);
+			}
+		}
 	}
 }

+ 0 - 8
mcs/class/System.XML/System.Xml/XmlLinkedNode.cs

@@ -17,7 +17,6 @@ namespace System.Xml
 		#region Fields
 
 		XmlLinkedNode nextSibling;
-		XmlLinkedNode lastLinkedChild;
 
 		#endregion
 
@@ -73,13 +72,6 @@ namespace System.Xml
 			}
 		}
 
-		// copied this way from XmlElement
-		internal override XmlLinkedNode LastLinkedChild
-		{
-			get { return lastLinkedChild; }
-			set { lastLinkedChild = value; }
-		}
-
 		#endregion
 	}
 }

+ 95 - 63
mcs/class/System.XML/System.Xml/XmlNode.cs

@@ -24,6 +24,7 @@ namespace System.Xml
 		XmlDocument ownerDocument;
 		XmlNode parentNode;
 		StringBuilder tmpBuilder;
+		XmlLinkedNode lastLinkedChild;
 
 		#endregion
 
@@ -152,8 +153,8 @@ namespace System.Xml
 		}
 
 		internal virtual XmlLinkedNode LastLinkedChild {
-			get { return null; }
-			set { }
+			get { return lastLinkedChild; }
+			set { lastLinkedChild = value; }
 		}
 
 		public abstract string LocalName { get;	}
@@ -359,62 +360,11 @@ namespace System.Xml
 
 		public virtual XmlNode InsertBefore (XmlNode newChild, XmlNode refChild)
 		{
-			XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
-
-			if (NodeType != XmlNodeType.Element &&
-			    NodeType != XmlNodeType.Attribute &&
-			    NodeType != XmlNodeType.Document &&
-			    NodeType != XmlNodeType.DocumentFragment)
-				throw new InvalidOperationException (String.Format ("current node {0} is not allowed to have any children.", NodeType));
-
-			switch (NodeType) {
-			case XmlNodeType.Attribute:
-				switch (newChild.NodeType) {
-				case XmlNodeType.Text:
-				case XmlNodeType.EntityReference:
-					break;
-				default:
-					throw new ArgumentException (String.Format (
-						"Cannot insert specified type of node {0} as a child of this node {0}.", 
-						newChild.NodeType, NodeType));
-				}
-				break;
-			case XmlNodeType.Element:
-				switch (newChild.NodeType) {
-				case XmlNodeType.Attribute:
-				case XmlNodeType.Document:
-				case XmlNodeType.DocumentType:
-				case XmlNodeType.Entity:
-				case XmlNodeType.Notation:
-				case XmlNodeType.XmlDeclaration:
-					throw new ArgumentException ("Cannot insert specified type of node as a child of this node.");
-				}
-				break;
-			}
-
-			if (IsReadOnly)
-				throw new ArgumentException ("The specified node is readonly.");
-
-			if (newChild.OwnerDocument != ownerDoc)
-				throw new ArgumentException ("Can't append a node created by another document.");
-
-			if (refChild != null && newChild.OwnerDocument != refChild.OwnerDocument)
-					throw new ArgumentException ("argument nodes are on the different documents.");
-
-			if(this == ownerDoc && ownerDoc.DocumentElement != null && (newChild is XmlElement))
-				throw new XmlException ("multiple document element not allowed.");
-
-			// checking validity finished. then appending...
-
-			
-			if (newChild == this || isAncestorIntern(newChild))
-				throw new ArgumentException("Cannot insert a node or any ancestor of that node as a child of itself.");
-
-			return insertBeforeIntern (newChild, refChild);
+			return InsertBefore (newChild, refChild, true);
 		}
 
 		// check for the node to be one of node ancestors
-		internal bool isAncestorIntern(XmlNode newChild)
+		internal bool IsAncestor (XmlNode newChild)
 		{
 			XmlNode currNode = this.ParentNode;
 			while(currNode != null)
@@ -426,14 +376,17 @@ namespace System.Xml
 			return false;
 		}
 
-		internal XmlNode insertBeforeIntern (XmlNode newChild, XmlNode refChild)
+		internal XmlNode InsertBefore (XmlNode newChild, XmlNode refChild, bool checkNodeType)
 		{
+			if (checkNodeType)
+				CheckNodeInsertion (newChild, refChild);
+
 			XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
 
 			ownerDoc.onNodeInserting (newChild, this);
 
 			if(newChild.ParentNode != null)
-				newChild.ParentNode.RemoveChild (newChild);
+				newChild.ParentNode.RemoveChild (newChild, checkNodeType);
 
 			if(newChild.NodeType == XmlNodeType.DocumentFragment) {
 				int x = newChild.ChildNodes.Count;
@@ -476,11 +429,79 @@ namespace System.Xml
 						prev.NextLinkedSibling = newLinkedChild;
 					newLinkedChild.NextLinkedSibling = refChild as XmlLinkedNode;
 				}
+				switch (newChild.NodeType) {
+				case XmlNodeType.EntityReference:
+					((XmlEntityReference) newChild).SetReferencedEntityContent ();
+					break;
+				case XmlNodeType.Entity:
+					((XmlEntity) newChild).SetEntityContent ();
+					break;
+				case XmlNodeType.DocumentType:
+					foreach (XmlEntity ent in ((XmlDocumentType)newChild).Entities)
+						ent.SetEntityContent ();
+					break;
+				}
+
 				ownerDoc.onNodeInserted (newChild, newChild.ParentNode);
 			}
 			return newChild;
 		}
 
+		private void CheckNodeInsertion (XmlNode newChild, XmlNode refChild)
+		{
+			XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
+
+			if (NodeType != XmlNodeType.Element &&
+			    NodeType != XmlNodeType.Attribute &&
+			    NodeType != XmlNodeType.Document &&
+			    NodeType != XmlNodeType.DocumentFragment)
+				throw new InvalidOperationException (String.Format ("current node {0} is not allowed to have any children.", NodeType));
+
+			switch (NodeType) {
+			case XmlNodeType.Attribute:
+				switch (newChild.NodeType) {
+				case XmlNodeType.Text:
+				case XmlNodeType.EntityReference:
+					break;
+				default:
+					throw new ArgumentException (String.Format (
+						"Cannot insert specified type of node {0} as a child of this node {0}.", 
+						newChild.NodeType, NodeType));
+				}
+				break;
+			case XmlNodeType.Element:
+				switch (newChild.NodeType) {
+				case XmlNodeType.Attribute:
+				case XmlNodeType.Document:
+				case XmlNodeType.DocumentType:
+				case XmlNodeType.Entity:
+				case XmlNodeType.Notation:
+				case XmlNodeType.XmlDeclaration:
+					throw new ArgumentException ("Cannot insert specified type of node as a child of this node.");
+				}
+				break;
+			}
+
+			if (IsReadOnly)
+				throw new ArgumentException ("The specified node is readonly.");
+
+			if (newChild.OwnerDocument != ownerDoc)
+				throw new ArgumentException ("Can't append a node created by another document.");
+
+			if (refChild != null && newChild.OwnerDocument != refChild.OwnerDocument)
+					throw new ArgumentException ("argument nodes are on the different documents.");
+
+			if(this == ownerDoc && ownerDoc.DocumentElement != null && (newChild is XmlElement))
+				throw new XmlException ("multiple document element not allowed.");
+
+			// checking validity finished. then appending...
+
+			
+			if (newChild == this || IsAncestor (newChild))
+				throw new ArgumentException("Cannot insert a node or any ancestor of that node as a child of itself.");
+
+		}
+
 		public virtual void Normalize ()
 		{
 //			if (tmpBuilder == null)
@@ -559,12 +580,11 @@ namespace System.Xml
 
 		public virtual XmlNode RemoveChild (XmlNode oldChild)
 		{
-			XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
-			if(oldChild.ParentNode != this)
-				throw new XmlException ("specified child is not child of this node.");
-
-			ownerDoc.onNodeRemoving (oldChild, oldChild.ParentNode);
+			return RemoveChild (oldChild, true);
+		}
 
+		private void CheckNodeRemoval ()
+		{
 			if (NodeType != XmlNodeType.Attribute && 
 				NodeType != XmlNodeType.Element && 
 				NodeType != XmlNodeType.Document && 
@@ -573,6 +593,18 @@ namespace System.Xml
 
 			if (IsReadOnly)
 				throw new ArgumentException (String.Format ("This {0} node is read only.", NodeType));
+		}
+
+		internal XmlNode RemoveChild (XmlNode oldChild, bool checkNodeType)
+		{
+			XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
+			if(oldChild.ParentNode != this)
+				throw new XmlException ("specified child is not child of this node.");
+
+			ownerDoc.onNodeRemoving (oldChild, oldChild.ParentNode);
+
+			if (checkNodeType)
+				CheckNodeRemoval ();
 
 			if (Object.ReferenceEquals (LastLinkedChild, LastLinkedChild.NextLinkedSibling) && Object.ReferenceEquals (LastLinkedChild, oldChild))
 				// If there is only one children, simply clear.
@@ -609,7 +641,7 @@ namespace System.Xml
 			if(oldChild.ParentNode != this)
 				throw new InvalidOperationException ("oldChild is not a child of this node.");
 			
-			if (newChild == this || isAncestorIntern(newChild))
+			if (newChild == this || IsAncestor (newChild))
 				throw new ArgumentException("Cannot insert a node or any ancestor of that node as a child of itself.");
 			
 			foreach(XmlNode n in ChildNodes) {

+ 4 - 5
mcs/class/System.XML/System.Xml/XmlNodeReader.cs

@@ -905,12 +905,11 @@ namespace System.Xml
 		{
 			if (NodeType != XmlNodeType.EntityReference)
 				throw new InvalidOperationException ("The current node is not an Entity Reference");
-			XmlEntity entity = document.DocumentType != null ?
-				document.DocumentType.Entities.GetNamedItem (Name) as XmlEntity : null;
 
-			// MS.NET seems simply ignoring undeclared entity reference ;-(
-			string replacementText =
-				(entity != null) ? entity.InnerText : String.Empty;
+			// FIXME: Now that XmlEntityReference holds the target 
+			// entity's child nodes, we don't have to use 
+			// XmlTextReader and simply use those nodes directly.
+			string replacementText = current.InnerXml;
 
 			XmlNodeType xmlReaderNodeType = 
 				(current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute) ?

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

@@ -49,12 +49,13 @@ namespace System.Xml
 			get { return true; } // Notation nodes are always read-only
 		}
 
+/*
 		internal override XmlLinkedNode LastLinkedChild {
 			get { return lastChild; }
 
 			set { lastChild = value; }
 		}
-
+*/
 		public override string LocalName {
 			get { return localName; }
 		}

+ 4 - 2
mcs/class/System.XML/System.Xml/XmlTextReader.cs

@@ -1682,7 +1682,8 @@ namespace System.Xml
 				currentAttributeToken.LineNumber = line;
 				currentAttributeToken.LinePosition = column;
 
-				currentAttributeToken.Name = ReadName ();
+				currentAttributeToken.LocalName = 
+					currentAttributeToken.Name = ReadName ();
 				ExpectAfterWhitespace ('=');
 				SkipWhitespace ();
 				ReadAttributeValueTokens (-1);
@@ -1719,7 +1720,7 @@ namespace System.Xml
 			IncrementAttributeValueToken ();
 			XmlTokenInfo vti = attributeValueTokens [currentAttributeValue];
 			vti.Value = value;
-			SetProperties (vti, XmlNodeType.Text, name, false, value, false);
+			SetProperties (vti, XmlNodeType.Text, String.Empty, false, value, false);
 			attributeCount++;
 		}
 
@@ -2220,6 +2221,7 @@ namespace System.Xml
 				AddAttribute ("PUBLIC", publicId);
 			if (systemId != null)
 				AddAttribute ("SYSTEM", systemId);
+			currentAttribute = currentAttributeValue = -1;
 		}
 
 		internal DTDObjectModel GenerateDTDObjectModel (string name, string publicId,