2004-02-06 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 5 Feb 2004 16:05:56 +0000 (16:05 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 5 Feb 2004 16:05:56 +0000 (16:05 -0000)
* DTDValidatingReader.cs : Fixed MoveToElement() that causes incorrect
  IsDefault and Depth.
* XmlAttribute.cs : Fixed .ctor(). Omit more namespace check when
  checkNamespace = false.
* XmlNamedNodeMap.cs : Fixed SetNamedItem() to raise events.
* XmlAttributeCollection.cs : Reimplemented InsertAfter to use
  InsertBefore() (similar to XmlNode).
* XmlDocument.cs : Added internal .ctor().  Reimplemented ReadNode()
  as recursive, to make event order compatible.
* XmlDocumentType.cs : Use SetNamedItem() (to raise events).
* XmlElement.cs : Some refactory.  Fixed SetAttributeNode() with
  string name to block prefixed name.
* XmlEntity.cs : Don't raise events on setting contents.
* XmlNode.cs : Some refactory. Added raiseEvent argument to internal
  InsertBefore().
* XmlEntityReference.cs : related fix for XmlNode change.
* XmlTextReader.cs : When the reader is on "attributes" of xmldecl or
  doctype, Depth 1 lower than usual attribute. Split large function.

svn path=/trunk/mcs/; revision=22799

12 files changed:
mcs/class/System.XML/System.Xml/ChangeLog
mcs/class/System.XML/System.Xml/DTDValidatingReader.cs
mcs/class/System.XML/System.Xml/XmlAttribute.cs
mcs/class/System.XML/System.Xml/XmlAttributeCollection.cs
mcs/class/System.XML/System.Xml/XmlDocument.cs
mcs/class/System.XML/System.Xml/XmlDocumentType.cs
mcs/class/System.XML/System.Xml/XmlElement.cs
mcs/class/System.XML/System.Xml/XmlEntity.cs
mcs/class/System.XML/System.Xml/XmlEntityReference.cs
mcs/class/System.XML/System.Xml/XmlNamedNodeMap.cs
mcs/class/System.XML/System.Xml/XmlNode.cs
mcs/class/System.XML/System.Xml/XmlTextReader.cs

index 99e8f13e2016af8d09f0379311575176d153f2a8..e47cc98becc3ff437e70296529826759ea7a2db9 100644 (file)
@@ -1,3 +1,24 @@
+2004-02-06  Atsushi Enomoto <atsushi@ximian.com>
+
+       * DTDValidatingReader.cs : Fixed MoveToElement() that causes incorrect
+         IsDefault and Depth.
+       * XmlAttribute.cs : Fixed .ctor(). Omit more namespace check when 
+         checkNamespace = false.
+       * XmlNamedNodeMap.cs : Fixed SetNamedItem() to raise events.
+       * XmlAttributeCollection.cs : Reimplemented InsertAfter to use
+         InsertBefore() (similar to XmlNode).
+       * XmlDocument.cs : Added internal .ctor().  Reimplemented ReadNode()
+         as recursive, to make event order compatible.
+       * XmlDocumentType.cs : Use SetNamedItem() (to raise events).
+       * XmlElement.cs : Some refactory.  Fixed SetAttributeNode() with 
+         string name to block prefixed name.
+       * XmlEntity.cs : Don't raise events on setting contents.
+       * XmlNode.cs : Some refactory. Added raiseEvent argument to internal
+         InsertBefore().
+       * XmlEntityReference.cs : related fix for XmlNode change.
+       * XmlTextReader.cs : When the reader is on "attributes" of xmldecl or
+         doctype, Depth 1 lower than usual attribute. Split large function.
+
 2004-02-05  Atsushi Enomoto <atsushi@ximian.com>
 
        * XmlConvert.cs : ToSingle() and ToDouble() should be culture 
index ab3a36146dcd5541d95dddc916039026ab7f9924..9389a5331cde55e74cc996fcf4ce72e638b5fc7f 100644 (file)
@@ -228,7 +228,7 @@ namespace Mono.Xml
                                return false;
 
                        bool b = reader.MoveToElement ();
-                       if (!b)
+                       if (!b && !IsDefault)
                                return false;
                        currentAttribute = null;
                        consumedAttribute = false;
@@ -719,8 +719,6 @@ namespace Mono.Xml
                                                break;
                                        case XmlTokenizedType.IDREFS:
                                                foreach (string idref in list) {
-                                                       // FIXME: is this normalization required?
-//                                                     string each = FilterNormalization (def.Name, idref);
                                                        if (!idList.Contains (idref))
                                                                missingIDReferences.Add (idref);
                                                }
index 23efb35d5f758d880baaa05e01461ec7f4494f84..9092029bf6ae868a6135c2b18015ab324180fd76 100644 (file)
@@ -50,12 +50,14 @@ namespace System.Xml
                                namespaceURI = String.Empty;
 
                        // Prefix "xml" should be also checked (http://www.w3.org/XML/xml-names-19990114-errata#NE05)
-                       // but MS.NET ignores such case.
-                       if (prefix == "xmlns" || (prefix == "" && localName == "xmlns"))
-                               if (namespaceURI != XmlNamespaceManager.XmlnsXmlns)
-                                       throw new ArgumentException ("Invalid attribute namespace for namespace declaration.");
-                       else if (prefix == "xml" && namespaceURI != XmlNamespaceManager.XmlnsXml)
+                       // but MS.NET ignores such case
+                       if (checkNamespace) {
+                               if (prefix == "xmlns" || (prefix == "" && localName == "xmlns"))
+                                       if (namespaceURI != XmlNamespaceManager.XmlnsXmlns)
+                                               throw new ArgumentException ("Invalid attribute namespace for namespace declaration.");
+                               else if (prefix == "xml" && namespaceURI != XmlNamespaceManager.XmlnsXml)
                                        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.
index cb24ab1d04438539d81a3250860defbae81d8f9f..d1d63a20f9db73a030537532a3193aecf0a35e61 100644 (file)
@@ -83,58 +83,39 @@ namespace System.Xml
 
                public virtual XmlAttribute InsertAfter (XmlAttribute newNode, XmlAttribute refNode)
                {
-                       if(newNode.OwnerDocument != this.ownerDocument)
-                               throw new ArgumentException ("different document created this newNode.");
-
-                       ownerDocument.onNodeInserting (newNode, null);
-
-                       int pos = Nodes.Count + 1;
-                       if(refNode != null)
-                       {
-                               for(int i=0; i<Nodes.Count; i++)
-                               {
-                                       XmlNode n = Nodes [i] as XmlNode;
-                                       if(n == refNode)
-                                       {
-                                               pos = i + 1;
-                                               break;
-                                       }
-                               }
-                               if(pos > Nodes.Count)
-                                       throw new XmlException ("refNode not found in this collection.");
+                       if (refNode == null) {
+                               if (Nodes.Count == 0)
+                                       return InsertBefore (newNode, null);
+                               else
+                                       return InsertBefore (newNode, this [0]);
                        }
-                       else
-                               pos = 0;
-                       SetNamedItem (newNode, pos);
+                       for (int i = 0; i < Nodes.Count; i++)
+                               if (refNode == Nodes [i])
+                                       return InsertBefore (newNode, Nodes.Count == i + 1 ? null : this [i + 1]);
 
-                       ownerDocument.onNodeInserted (newNode, null);
-
-                       return newNode;
+                       throw new ArgumentException ("refNode not found in this collection.");
                }
 
                public virtual XmlAttribute InsertBefore (XmlAttribute newNode, XmlAttribute refNode)
                {
-                       if(newNode.OwnerDocument != ownerDocument)
+                       if (newNode.OwnerDocument != ownerDocument)
                                throw new ArgumentException ("different document created this newNode.");
 
                        ownerDocument.onNodeInserting (newNode, null);
 
                        int pos = Nodes.Count;
-                       if(refNode != null)
-                       {
-                               for(int i=0; i<Nodes.Count; i++)
-                               {
+                       if (refNode != null) {
+                               for (int i = 0; i < Nodes.Count; i++) {
                                        XmlNode n = Nodes [i] as XmlNode;
-                                       if(n == refNode)
-                                       {
+                                       if (n == refNode) {
                                                pos = i;
                                                break;
                                        }
                                }
-                               if(pos == Nodes.Count)
-                                       throw new XmlException ("refNode not found in this collection.");
+                               if (pos == Nodes.Count)
+                                       throw new ArgumentException ("refNode not found in this collection.");
                        }
-                       SetNamedItem (newNode, pos);
+                       SetNamedItem (newNode, pos, false);
 
                        ownerDocument.onNodeInserted (newNode, null);
 
@@ -208,8 +189,15 @@ namespace System.Xml
                        XmlAttribute attr = node as XmlAttribute;
                        if (attr.OwnerElement != null)
                                throw new InvalidOperationException ("This attribute is already set to another element.");
+
+                       ownerElement.OwnerDocument.onNodeInserting (node, ownerElement);
+
                        attr.SetOwnerElement (ownerElement);
-                       return AdjustIdenticalAttributes (node as XmlAttribute, base.SetNamedItem (node, -1) as XmlAttribute);
+                       XmlNode n = AdjustIdenticalAttributes (node as XmlAttribute, base.SetNamedItem (node, -1, false));
+
+                       ownerElement.OwnerDocument.onNodeInserted (node, ownerElement);
+
+                       return n as XmlAttribute;
                }
 
                internal void AddIdenticalAttribute ()
index 07969dafbf653c6dc58d119cf2c60a078ea441ca..7337acc697612c8e0753c4678700aeba92861094 100644 (file)
@@ -248,11 +248,16 @@ namespace System.Xml
                }
 
                public virtual XmlAttribute CreateAttribute (string prefix, string localName, string namespaceURI)
+               {
+                       return CreateAttribute (prefix, localName, namespaceURI, false, true);
+               }
+
+               internal XmlAttribute CreateAttribute (string prefix, string localName, string namespaceURI, bool atomizedNames, bool checkNamespace)
                {
                        if ((localName == null) || (localName == String.Empty))
                                throw new ArgumentException ("The attribute local name cannot be empty.");
 
-                       return new XmlAttribute (prefix, localName, namespaceURI, this, false, true);
+                       return new XmlAttribute (prefix, localName, namespaceURI, this, atomizedNames, checkNamespace);
                }
 
                public virtual XmlCDataSection CreateCDataSection (string data)
@@ -588,8 +593,10 @@ namespace System.Xml
                                loadMode = true;
                                do {
                                        XmlNode n = ReadNode (xmlReader);
-                                       if(n == null) break;
-                                       AppendChild (n);
+                                       if (n == null)
+                                               break;
+                                       if (preserveWhitespace || n.NodeType != XmlNodeType.Whitespace)
+                                               AppendChild (n);
                                } while (true);
                        } finally {
                                loadMode = false;
@@ -676,7 +683,7 @@ namespace System.Xml
                                reader.MoveToFirstAttribute ();
                        else if(reader.NodeType != XmlNodeType.Attribute)
                                throw new InvalidOperationException (MakeReaderErrorMessage ("bad position to read attribute.", reader));
-                       XmlAttribute attribute = CreateAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                       XmlAttribute attribute = CreateAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI, false, false); // different NameTable
                        ReadAttributeNodeValue (reader, attribute);
 
                        // Keep the current reader position
@@ -691,10 +698,10 @@ namespace System.Xml
                }
 
                // Reads attribute from XmlReader and then creates attribute value children. XmlAttribute also uses this.
-               internal void ReadAttributeNodeValue(XmlReader reader, XmlAttribute attribute)
+               internal void ReadAttributeNodeValue (XmlReader reader, XmlAttribute attribute)
                {
-                       while(reader.ReadAttributeValue ()) {
-                               if(reader.NodeType == XmlNodeType.EntityReference)
+                       while (reader.ReadAttributeValue ()) {
+                               if (reader.NodeType == XmlNodeType.EntityReference)
                                        // FIXME: if DocumentType is available, then try to resolve it.
                                        attribute.AppendChild (CreateEntityReference (reader.Name));
                                // FIXME: else if(NodeType == EndEntity) -- reset BaseURI and so on -- ;
@@ -706,10 +713,6 @@ namespace System.Xml
 
                public virtual XmlNode ReadNode (XmlReader reader)
                {
-                       XmlNode resultNode = null;
-                       XmlNode newNode = null;
-                       XmlNode currentNode = null;
-
                        switch (reader.ReadState) {
                        case ReadState.Interactive:
                                break;
@@ -720,146 +723,108 @@ namespace System.Xml
                                return null;
                        }
 
-                       int startDepth = reader.Depth;
-                       bool ignoredWhitespace;
-                       bool reachedEOF = false;
-
-                       do {
-                               ignoredWhitespace = false;
-                               if (reader.ReadState != ReadState.Interactive)
-                                       if (reachedEOF)
-                                               throw new Exception ("XML Reader reached to end while reading node.");
-                                       else
-                                               reachedEOF = true;
-                               switch (reader.NodeType) {
-
-                               case XmlNodeType.Attribute:
-                                       newNode = ReadAttributeNode (reader);
-                                       break;
+                       XmlNode n;
+                       switch (reader.NodeType) {
 
-                               case XmlNodeType.CDATA:
-                                       newNode = CreateCDataSection (reader.Value);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.Attribute:
+                               return ReadAttributeNode (reader);
 
-                               case XmlNodeType.Comment:
-                                       newNode = CreateComment (reader.Value);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.CDATA:
+                               n = CreateCDataSection (reader.Value);
+                               break;
 
-                               case XmlNodeType.Element:
-                                       XmlElement element = CreateElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
-                                       element.IsEmpty = reader.IsEmptyElement;
+                       case XmlNodeType.Comment:
+                               n = CreateComment (reader.Value);
+                               break;
 
-                                       // set the element's attributes.
-                                       while (reader.MoveToNextAttribute ()) {
-                                               element.SetAttributeNode (ReadAttributeNode (reader));
-                                       }
+                       case XmlNodeType.Element:
+                               XmlElement element = CreateElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                               element.IsEmpty = reader.IsEmptyElement;
 
+                               // set the element's attributes.
+                               if (reader.MoveToFirstAttribute ()) {
+                                       do {
+                                               element.SetAttributeNode (ReadAttributeNode (reader));
+                                       } while (reader.MoveToNextAttribute ());
                                        reader.MoveToElement ();
+                               }
 
-                                       // MS.NET adds element to document after its attributes are filled.
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (element);
-                                       else
-                                               resultNode = element;
-
-                                       if (!reader.IsEmptyElement)
-                                               currentNode = element;
+                               int depth = reader.Depth;
 
+                               if (element.IsEmpty) {
+                                       n = element;
                                        break;
+                               }
 
-                               case XmlNodeType.EndElement:
-                                       if (currentNode == null)
-                                               throw new XmlException ("Unexpected end element.");
-                                       else if (currentNode.Name != reader.Name)
-                                               throw new XmlException (reader as IXmlLineInfo, String.Format ("mismatch end tag. Expected {0} but found {1}", currentNode.Name, reader.Name));
-                                       currentNode = currentNode.ParentNode;
-                                       break;
+                               reader.Read ();
+                               while (reader.Depth > depth) {
+                                       n = ReadNode (reader);
+                                       if (preserveWhitespace || n.NodeType != XmlNodeType.Whitespace)
+                                               element.AppendChild (n);
+                               }
+                               n = element;
+                               break;
 
-                               case XmlNodeType.EndEntity:
-                                       break;  // no operation
+                       case XmlNodeType.ProcessingInstruction:
+                               n = CreateProcessingInstruction (reader.Name, reader.Value);
+                               break;
 
-                               case XmlNodeType.ProcessingInstruction:
-                                       newNode = CreateProcessingInstruction (reader.Name, reader.Value);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.Text:
+                               n = CreateTextNode (reader.Value);
+                               break;
 
-                               case XmlNodeType.Text:
-                                       newNode = CreateTextNode (reader.Value);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.XmlDeclaration:
+                               n = CreateXmlDeclaration ("1.0" , String.Empty, String.Empty);
+                               n.Value = reader.Value;
+                               break;
 
-                               case XmlNodeType.XmlDeclaration:
-                                       // empty strings are dummy, then gives over setting value contents to setter.
-                                       newNode = CreateXmlDeclaration ("1.0" , String.Empty, String.Empty);
-                                       ((XmlDeclaration)newNode).Value = reader.Value;
-                                       if(currentNode != null)
-                                               throw new XmlException (reader as IXmlLineInfo, "XmlDeclaration at invalid position.");
-                                       break;
+                       case XmlNodeType.DocumentType:
+                               DTDObjectModel dtd = null;
+                               XmlTextReader xtReader = reader as XmlTextReader;
+                               if (xtReader != null)
+                                       dtd = xtReader.DTD;
+                               XmlNodeReader xnReader = reader as XmlNodeReader;
+                               if (xnReader != null)
+                                       dtd = xnReader.GetInternalParserContext ().Dtd;
+                               XmlValidatingReader xvReader = reader as XmlValidatingReader;
+                               if (xvReader != null)
+                                       dtd = xvReader.GetInternalParserContext ().Dtd;
+                               IHasXmlParserContext ctxReader = reader as IHasXmlParserContext;
+                               if (ctxReader != null)
+                                       dtd = ctxReader.ParserContext.Dtd;
+
+                               if (dtd != null)
+                                       n = CreateDocumentType (dtd);
+                               else
+                                       n = CreateDocumentType (reader.Name, reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
+                               break;
 
-                               case XmlNodeType.DocumentType:
-                                       if(currentNode != null)
-                                               throw new XmlException (reader as IXmlLineInfo, "XmlDocumentType at invalid position.");
-
-                                       DTDObjectModel dtd = null;
-                                       XmlTextReader xtReader = reader as XmlTextReader;
-                                       if (xtReader != null)
-                                               dtd = xtReader.DTD;
-                                       XmlNodeReader xnReader = reader as XmlNodeReader;
-                                       if (xnReader != null)
-                                               dtd = xnReader.GetInternalParserContext ().Dtd;
-                                       XmlValidatingReader xvReader = reader as XmlValidatingReader;
-                                       if (xvReader != null)
-                                               dtd = xvReader.GetInternalParserContext ().Dtd;
-                                       IHasXmlParserContext ctxReader = reader as IHasXmlParserContext;
-                                       if (ctxReader != null)
-                                               dtd = ctxReader.ParserContext.Dtd;
-
-                                       if (dtd != null)
-                                               newNode = CreateDocumentType (dtd);
-                                       else
-                                               newNode = CreateDocumentType (reader.Name, reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
+                       case XmlNodeType.EntityReference:
+                               if (this.loadMode && this.DocumentType != null &&
+                                       DocumentType.Entities.GetNamedItem (reader.Name) == null)
+                                       throw new XmlException ("Reference to undeclared entity was found.");
 
-                                       break;
+                               n = CreateEntityReference (reader.Name);
+                               break;
 
-                               case XmlNodeType.EntityReference:
-                                       if (this.loadMode && this.DocumentType != null &&
-                                               DocumentType.Entities.GetNamedItem (reader.Name) == null)
-                                               throw new XmlException ("Reference to undeclared entity was found.");
-                                       newNode = CreateEntityReference (reader.Name);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.SignificantWhitespace:
+                               n = CreateSignificantWhitespace (reader.Value);
+                               break;
 
-                               case XmlNodeType.SignificantWhitespace:
-                                       newNode = CreateSignificantWhitespace (reader.Value);
-                                       if(currentNode != null)
-                                               currentNode.AppendChild (newNode);
-                                       break;
+                       case XmlNodeType.Whitespace:
+                               n = CreateWhitespace (reader.Value);
+                               break;
 
-                               case XmlNodeType.Whitespace:
-                                       if(PreserveWhitespace) {
-                                               newNode = CreateWhitespace (reader.Value);
-                                               if(currentNode != null)
-                                                       currentNode.AppendChild (newNode);
-                                       }
-                                       else
-                                               ignoredWhitespace = true;
-                                       break;
-                               }
-                               // Read next, except for reading attribute node.
-                               if (!(newNode is XmlAttribute) && !reader.Read ())
-                                       break;
-                       } while (ignoredWhitespace || reader.Depth > startDepth ||
-                               (reader.Depth == startDepth && reader.NodeType == XmlNodeType.EndElement));
-                       if (startDepth < reader.Depth && reader.EOF)
-                               throw new XmlException ("Unexpected end of xml reader.");
-                       return resultNode != null ? resultNode : newNode;
+                       case XmlNodeType.None:
+                               return null;
+
+                       default:
+                               // No idea why MS does throw NullReferenceException ;-P
+                               throw new NullReferenceException ("Unexpected node type " + reader.NodeType + ".");
+                       }
+
+                       reader.Read ();
+                       return n;
                }
 
                private string MakeReaderErrorMessage (string message, XmlReader reader)
index e40e9b06cb85b6a2192aee49254f553b448332fb..eaec0d13b26c7eaa02e70783077c469be51ba4d5 100644 (file)
@@ -49,12 +49,12 @@ namespace System.Xml
                        foreach (DTDEntityDeclaration decl in DTD.EntityDecls.Values) {
                                XmlNode n = new XmlEntity (decl.Name, decl.NotationName,
                                        decl.PublicId, decl.SystemId, OwnerDocument);
-                               entities.Nodes.Add (n);
+                               entities.SetNamedItem (n);
                        }
                        foreach (DTDNotationDeclaration decl in DTD.NotationDecls.Values) {
                                XmlNode n = new XmlNotation (decl.LocalName, decl.Prefix,
                                        decl.PublicId, decl.SystemId, OwnerDocument);
-                               notations.Nodes.Add (n);
+                               notations.SetNamedItem (n);
                        }
                }\r
 \r
index 1e7007a257ec91797535a82a5d10abb35197cada..4b9d553ecd8cdfbbc99755a6442387f66325d366 100644 (file)
@@ -95,12 +95,12 @@ namespace System.Xml
                                if (FirstChild != null && FirstChild.NodeType == XmlNodeType.Text)
                                        FirstChild.Value = value;
                                else {
-                                       if(FirstChild != null) {
+                                       if (FirstChild != null) {
                                                foreach (XmlNode n in ChildNodes)
                                                        this.RemoveChild (n);
                                        }
                                        // creates new Text node
-                                       AppendChild(OwnerDocument.CreateTextNode(value));
+                                       AppendChild (OwnerDocument.CreateTextNode (value));
                                }
                        }
                }
@@ -321,12 +321,11 @@ namespace System.Xml
 
                public virtual string SetAttribute (string localName, string namespaceURI, string value)
                {
-                       XmlAttribute attr = attributes[localName, namespaceURI];
-                       if(attr == null)
-                       {
-                               attr = OwnerDocument.CreateAttribute(localName, namespaceURI);
+                       XmlAttribute attr = attributes [localName, namespaceURI];
+                       if (attr == null) {
+                               attr = OwnerDocument.CreateAttribute (localName, namespaceURI);
                                attr.Value = value;
-                               attributes.SetNamedItem(attr);
+                               attributes.SetNamedItem (attr);
                        }
                        else
                                attr.Value = value;
@@ -339,35 +338,38 @@ namespace System.Xml
                                throw new InvalidOperationException (
                                        "Specified attribute is already an attribute of another element.");
 
-                       XmlNode oldAttr = Attributes.SetNamedItem(newAttr);
-                       return oldAttr != null ? oldAttr as XmlAttribute : null;
+                       return Attributes.SetNamedItem (newAttr) as XmlAttribute;
                }
 
                public virtual XmlAttribute SetAttributeNode (string localName, string namespaceURI)
                {
-                       XmlDocument xmlDoc = this.OwnerDocument;
-                       XmlAttribute xmlAttribute = new XmlAttribute (String.Empty, localName, namespaceURI, xmlDoc, false, true);
-                       return this.attributes.Append (xmlAttribute);
+                       // Note that this constraint is only for this method.
+                       // SetAttribute() allows prefixed name.
+                       XmlConvert.VerifyNCName (localName);
+
+                       return Attributes.Append (OwnerDocument.CreateAttribute (String.Empty, localName, namespaceURI, false, true));
                }
 
                public override void WriteContentTo (XmlWriter w)
                {
-                       foreach(XmlNode childNode in ChildNodes)
-                               childNode.WriteTo(w);
+                       int count = ChildNodes.Count;
+                       for (int i = 0; i < count; i++)
+                               ChildNodes [i].WriteTo (w);
                }
 
                public override void WriteTo (XmlWriter w)
                {
                        w.WriteStartElement (NamespaceURI == null || NamespaceURI.Length == 0 ? String.Empty : Prefix, LocalName, NamespaceURI);
 
-                       foreach(XmlAttribute attributeNode in Attributes)
-                               if (attributeNode.Specified)
-                                       attributeNode.WriteTo(w);
+                       for (int i = 0; i < Attributes.Count; i++)
+                               if (Attributes [i].Specified)
+                                       Attributes [i].WriteTo(w);
+
                        if (IsEmpty)
                                w.WriteEndElement ();
                        else {
-                               WriteContentTo(w);
-                               w.WriteFullEndElement();
+                               WriteContentTo (w);
+                               w.WriteFullEndElement ();
                        }
                }
 
index 80fd0f8d1141b0386797878c3bed63dc8b4c2fe1..43f89263ef4407b262fe972c6f64a8b9e97fd1ac 100755 (executable)
@@ -146,7 +146,7 @@ namespace System.Xml
                        do {
                                XmlNode n = OwnerDocument.ReadNode (xmlReader);
                                if(n == null) break;
-                               InsertBefore (n, null, false);
+                               InsertBefore (n, null, false, false);
                        } while (true);
                }\r
                #endregion
index 18615a9bdd375a3c4db62012e69abc05b868c366..0635e2ba98ea6d343b8e884b376cff44eb8222d9 100644 (file)
@@ -85,11 +85,11 @@ namespace System.Xml
 \r
                        XmlEntity ent = doctype.Entities.GetNamedItem (Name) as XmlEntity;\r
                        if (ent == null)\r
-                               InsertBefore (OwnerDocument.CreateTextNode (String.Empty), null, false);\r
+                               InsertBefore (OwnerDocument.CreateTextNode (String.Empty), null, false, true);\r
                        else {\r
                                ent.SetEntityContent ();\r
                                for (int i = 0; i < ent.ChildNodes.Count; i++)\r
-                                       InsertBefore (ent.ChildNodes [i].CloneNode (true), null, false);\r
+                                       InsertBefore (ent.ChildNodes [i].CloneNode (true), null, false, true);\r
                        }\r
                }\r
        }\r
index 1c49d38a8d8137903d2c4d978e08d3d04d602fd5..aac2fd1e4701a25607d2a5edc23572ee927fab09 100644 (file)
@@ -88,29 +88,45 @@ namespace System.Xml
 
                public virtual XmlNode SetNamedItem (XmlNode node)
                {
-                       return SetNamedItem(node, -1);
+                       return SetNamedItem (node, -1, true);
                }
 
-               internal XmlNode SetNamedItem (XmlNode node, int pos)
+               public virtual XmlNode SetNamedItem (XmlNode node, bool raiseEvent)
+               {
+                       return SetNamedItem (node, -1, raiseEvent);
+               }
+
+               internal XmlNode SetNamedItem (XmlNode node, int pos, bool raiseEvent)
                {
                        if (readOnly || (node.OwnerDocument != parent.OwnerDocument))
                                throw new ArgumentException ("Cannot add to NodeMap.");
 
-                       foreach (XmlNode x in nodeList)
-                               if(x.LocalName == node.LocalName && x.NamespaceURI == node.NamespaceURI) {
-                                       nodeList.Remove (x);
-                                       if (pos < 0)
-                                               nodeList.Add (node);
-                                       else
-                                               nodeList.Insert (pos, node);
-                                       return x;
+                       if (raiseEvent)
+                               parent.OwnerDocument.onNodeInserting (node, parent);
+
+                       try {
+                               foreach (XmlNode x in nodeList) {
+                                       if(x.LocalName == node.LocalName && x.NamespaceURI == node.NamespaceURI) {
+                                               nodeList.Remove (x);
+                                               if (pos < 0)
+                                                       nodeList.Add (node);
+                                               else
+                                                       nodeList.Insert (pos, node);
+                                               return x;
+                                       }
                                }
                        
-                       if(pos < 0)
-                               nodeList.Add (node);
-                       else
-                               nodeList.Insert(pos, node);
-                       return null;
+                               if(pos < 0)
+                                       nodeList.Add (node);
+                               else
+                                       nodeList.Insert (pos, node);
+
+                               return null;
+                       } finally {
+                               if (raiseEvent)
+                                       parent.OwnerDocument.onNodeInserted (node, parent);
+                       }
+
                }
 
                internal ArrayList Nodes { get { return nodeList; } }
index 70f93301f4486e8582b9ac92ea7921ef6dafca17..7e779dc28e4168b09a3366d7ca44405ab51314e0 100644 (file)
@@ -343,24 +343,23 @@ namespace System.Xml
 
                public virtual XmlNode InsertAfter (XmlNode newChild, XmlNode refChild)
                {
-                       // I assume that insertAfter(n1, n2) equals to InsertBefore(n1, n2.PreviousSibling).
+                       // InsertAfter(n1, n2) is equivalent to InsertBefore(n1, n2.PreviousSibling).
 
                        // I took this way because current implementation 
-                       // Calling InsertAfter() from InsertBefore() is
-                       // subsequently to use 'NextSibling' which is
-                       // faster than 'PreviousSibling' (these children are 
-                       // forward-only linked list).
+                       // Calling InsertBefore() in this method is faster than
+                       // the counterpart, since NextSibling is faster than 
+                       // PreviousSibling (these children are forward-only list).
                        XmlNode argNode = null;
-                       if(refChild != null)
+                       if (refChild != null)
                                argNode = refChild.NextSibling;
-                       else if(ChildNodes.Count > 0)
+                       else if (ChildNodes.Count > 0)
                                argNode = FirstChild;
                        return InsertBefore (newChild, argNode);
                }
 
                public virtual XmlNode InsertBefore (XmlNode newChild, XmlNode refChild)
                {
-                       return InsertBefore (newChild, refChild, true);
+                       return InsertBefore (newChild, refChild, true, true);
                }
 
                // check for the node to be one of node ancestors
@@ -376,21 +375,22 @@ namespace System.Xml
                        return false;
                }
 
-               internal XmlNode InsertBefore (XmlNode newChild, XmlNode refChild, bool checkNodeType)
+               internal XmlNode InsertBefore (XmlNode newChild, XmlNode refChild, bool checkNodeType, bool raiseEvent)
                {
                        if (checkNodeType)
                                CheckNodeInsertion (newChild, refChild);
 
-                       XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument)this : OwnerDocument;
+                       XmlDocument ownerDoc = (NodeType == XmlNodeType.Document) ? (XmlDocument) this : OwnerDocument;
 
-                       ownerDoc.onNodeInserting (newChild, this);
+                       if (raiseEvent)
+                               ownerDoc.onNodeInserting (newChild, this);
 
-                       if(newChild.ParentNode != null)
+                       if (newChild.ParentNode != null)
                                newChild.ParentNode.RemoveChild (newChild, checkNodeType);
 
-                       if(newChild.NodeType == XmlNodeType.DocumentFragment) {
+                       if (newChild.NodeType == XmlNodeType.DocumentFragment) {
                                int x = newChild.ChildNodes.Count;
-                               for(int i=0; i<x; i++) {
+                               for (int i = 0; i < x; i++) {
                                        XmlNode n = newChild.ChildNodes [0];
                                        this.InsertBefore (n, refChild);        // recursively invokes events. (It is compatible with MS implementation.)
                                }
@@ -401,29 +401,27 @@ namespace System.Xml
 
                                newLinkedChild.parentNode = this;
 
-                               if(refChild == null) {
-                                       // append last, so:
-                                       // * set nextSibling of previous lastchild to newChild
-                                       // * set lastchild = newChild
-                                       // * set next of newChild to firstChild
-                                       if(LastLinkedChild != null) {
-                                               XmlLinkedNode formerFirst = FirstChild as XmlLinkedNode;
+                               if (refChild == null) {
+                                       // newChild is the last child:
+                                       // * set newChild as NextSibling of the existing lastchild
+                                       // * set LastChild = newChild
+                                       // * set NextSibling of newChild as FirstChild
+                                       if (LastLinkedChild != null) {
+                                               XmlLinkedNode formerFirst = (XmlLinkedNode) FirstChild;
                                                LastLinkedChild.NextLinkedSibling = newLinkedChild;
                                                LastLinkedChild = newLinkedChild;
                                                newLinkedChild.NextLinkedSibling = formerFirst;
-                                       }
-                                       else {
+                                       } else {
                                                LastLinkedChild = newLinkedChild;
                                                LastLinkedChild.NextLinkedSibling = newLinkedChild;     // FirstChild
                                        }
-                               }
-                               else {
-                                       // append not last, so:
+                               } else {
+                                       // newChild is not the last child:
                                        // * if newchild is first, then set next of lastchild is newChild.
                                        //   otherwise, set next of previous sibling to newChild
                                        // * set next of newChild to refChild
                                        XmlLinkedNode prev = refChild.PreviousSibling as XmlLinkedNode;
-                                       if(prev == null)
+                                       if (prev == null)
                                                LastLinkedChild.NextLinkedSibling = newLinkedChild;
                                        else
                                                prev.NextLinkedSibling = newLinkedChild;
@@ -442,7 +440,8 @@ namespace System.Xml
                                        break;
                                }
 
-                               ownerDoc.onNodeInserted (newChild, newChild.ParentNode);
+                               if (raiseEvent)
+                                       ownerDoc.onNodeInserted (newChild, newChild.ParentNode);
                        }
                        return newChild;
                }
@@ -601,7 +600,8 @@ namespace System.Xml
                        if(oldChild.ParentNode != this)
                                throw new XmlException ("specified child is not child of this node.");
 
-                       ownerDoc.onNodeRemoving (oldChild, oldChild.ParentNode);
+                       if (checkNodeType)
+                               ownerDoc.onNodeRemoving (oldChild, oldChild.ParentNode);
 
                        if (checkNodeType)
                                CheckNodeRemoval ();
@@ -630,7 +630,8 @@ namespace System.Xml
                                oldLinkedChild.NextLinkedSibling = null;
                                }
 
-                       ownerDoc.onNodeRemoved (oldChild, oldChild.ParentNode);
+                       if (checkNodeType)
+                               ownerDoc.onNodeRemoved (oldChild, oldChild.ParentNode);
                        oldChild.parentNode = null;     // clear parent 'after' above logic.
 
                        return oldChild;
index c73ca56f8d0a6c22c8cb0b8809c0eae9f4ee2994..81579b864483451e371d5bee63da19e2941e298d 100644 (file)
@@ -11,8 +11,6 @@
 
 // FIXME:
 //
-//   NameTables aren't being used completely yet.
-//
 //   Some thought needs to be given to performance. There's too many
 //   strings being allocated.
 //
@@ -140,10 +138,11 @@ namespace System.Xml
                public override int Depth
                {
                        get {
+                               int nodeTypeMod = currentToken.NodeType == XmlNodeType.Element  ? 0 : -1;
                                if (currentAttributeValue >= 0)
-                                       return elementDepth + 2; // inside attribute value.
+                                       return nodeTypeMod + elementDepth + 2; // inside attribute value.
                                else if (currentAttribute >= 0)
-                                       return elementDepth + 1;
+                                       return nodeTypeMod + elementDepth + 1;
                                return elementDepth;
                        }
                }
@@ -1667,7 +1666,7 @@ namespace System.Xml
 
                // The reader is positioned on the first character of
                // the attribute name.
-               private void ReadAttributes (bool endsWithQuestion)
+               private void ReadAttributes (bool isXmlDecl)
                {
                        int peekChar = -1;
                        bool requireWhitespace = false;
@@ -1699,7 +1698,7 @@ namespace System.Xml
                                if (!SkipWhitespace ())
                                        requireWhitespace = true;
                                peekChar = PeekChar ();
-                               if (endsWithQuestion) {
+                               if (isXmlDecl) {
                                        if (peekChar == '?')
                                                break;
                                }
@@ -1810,19 +1809,7 @@ namespace System.Xml
                                        Expect (';');
                                        int predefined = XmlChar.GetPredefinedEntity (entName);
                                        if (predefined < 0) {
-                                               DTDEntityDeclaration entDecl = 
-                                                       DTD == null ? null : DTD.EntityDecls [entName];
-                                               if (DTD != null && resolver != null && entDecl == null)
-                                                       throw new XmlException (this as IXmlLineInfo, "Entity declaration does not exist.");
-                                               if (entDecl != null && entDecl.HasExternalReference)
-                                                       throw new XmlException (this as IXmlLineInfo,
-                                                               "Reference to external entities is not allowed in the value of an attribute.");
-                                               if (isStandalone && !entDecl.IsInternalSubset)
-                                                       throw new XmlException (this as IXmlLineInfo,
-                                                               "Reference to external entities is not allowed in the value of an attribute.");
-                                               if (entDecl != null && entDecl.EntityValue.IndexOf ('<') >= 0)
-                                                       throw new XmlException (this as IXmlLineInfo,
-                                                               "Attribute must not contain character '<' either directly or indirectly by way of entity references.");
+                                               CheckAttributeEntityReferenceWFC (entName);
                                                currentAttributeValueToken.Value = CreateValueString ();
                                                currentAttributeValueToken.NodeType = XmlNodeType.Text;
                                                if (!isNewToken)
@@ -1852,6 +1839,24 @@ namespace System.Xml
 
                }
 
+               private void CheckAttributeEntityReferenceWFC (string entName)
+               {
+                       DTDEntityDeclaration entDecl = 
+                               DTD == null ? null : DTD.EntityDecls [entName];
+                       if (DTD != null && resolver != null && entDecl == null)
+                               throw new XmlException (this, "Referenced entity does not exist.");
+
+                       if (entDecl == null)
+                               return;
+
+                       if (entDecl.HasExternalReference)
+                               throw new XmlException (this, "Reference to external entities is not allowed in the value of an attribute.");
+                       if (isStandalone && !entDecl.IsInternalSubset)
+                               throw new XmlException (this, "Reference to external entities is not allowed in the internal subset.");
+                       if (entDecl.EntityValue.IndexOf ('<') >= 0)
+                               throw new XmlException (this, "Attribute must not contain character '<' either directly or indirectly by way of entity references.");
+               }
+
                // The reader is positioned on the first character
                // of the target.
                //