Merge pull request #93 from konrad-kruczynski/dispatcher_timer_fix
[mono.git] / mcs / class / System.XML / System.Xml / XmlDocument.cs
index fa13f3828ace69376ea95203163e7ff2a3c1bc16..6a9627da2b01927745171e1177a159d2024dcd32 100644 (file)
@@ -52,6 +52,8 @@ namespace System.Xml
        public class XmlDocument : XmlNode, IHasXmlChildNode
        {
                #region Fields
+               static readonly Type [] optimal_create_types = new Type [] {typeof (string), typeof (string), typeof (string)};
+               bool optimal_create_element, optimal_create_attribute;
 
                XmlNameTable nameTable;
                string baseURI = String.Empty;
@@ -61,6 +63,7 @@ namespace System.Xml
                Hashtable idTable = new Hashtable ();
                XmlNameEntryCache nameCache;
                XmlLinkedNode lastLinkedChild;
+               XmlAttribute nsNodeXml;
 #if NET_2_0
                XmlSchemaSet schemas;
                IXmlSchemaInfo schemaInfo;
@@ -99,6 +102,10 @@ namespace System.Xml
                        nameCache = new XmlNameEntryCache (nameTable);
                        AddDefaultNameTableKeys ();
                        resolver = new XmlUrlResolver ();
+                       
+                       Type type = GetType ();
+                       optimal_create_element = type.GetMethod ("CreateElement", optimal_create_types).DeclaringType == typeof (XmlDocument);
+                       optimal_create_attribute = type.GetMethod ("CreateAttribute", optimal_create_types).DeclaringType == typeof (XmlDocument);
                }
                #endregion
 
@@ -120,6 +127,16 @@ namespace System.Xml
 
                #region Properties
 
+               internal XmlAttribute NsNodeXml {
+                       get {
+                               if (nsNodeXml == null) {
+                                       nsNodeXml = CreateAttribute ("xmlns", "xml", "http://www.w3.org/2000/xmlns/");
+                                       nsNodeXml.Value = "http://www.w3.org/XML/1998/namespace";
+                               }
+                               return nsNodeXml;
+                       }
+               }
+
                XmlLinkedNode IHasXmlChildNode.LastLinkedChild {
                        get { return lastLinkedChild; }
                        set { lastLinkedChild = value; }
@@ -162,6 +179,12 @@ namespace System.Xml
                        get { return implementation; }
                }
 
+#if NET_4_0
+               public override string InnerText {
+                       set { throw new InvalidOperationException (); }
+               }
+#endif
+
                public override string InnerXml {
                        get {
                                return base.InnerXml;
@@ -253,7 +276,11 @@ namespace System.Xml
                }
 
                public XmlSchemaSet Schemas {
-                       get { return schemas; }
+                       get {
+                               if (schemas == null)
+                                       schemas = new XmlSchemaSet ();
+                               return schemas;
+                       }
                        set { schemas = value; }
                }
 
@@ -312,15 +339,18 @@ namespace System.Xml
 
                public virtual XmlAttribute CreateAttribute (string prefix, string localName, string namespaceURI)
                {
-                       return CreateAttribute (prefix, localName, namespaceURI, false, true);
+                       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);
                }
 
                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, atomizedNames, checkNamespace);
+                       if (optimal_create_attribute)
+                               return new XmlAttribute (prefix, localName, namespaceURI, this, atomizedNames, checkNamespace);
+                       else
+                               return CreateAttribute (prefix, localName, namespaceURI);
                }
 
                public virtual XmlCDataSection CreateCDataSection (string data)
@@ -379,14 +409,29 @@ namespace System.Xml
                        string localName,
                        string namespaceURI)
                {
-                       if ((localName == null) || (localName == String.Empty))
-                               throw new ArgumentException ("The local name for elements or attributes cannot be null or an empty string.");
                        // LAMESPEC: MS.NET has a weird behavior that they can Load() from XmlTextReader 
                        // whose Namespaces = false, but their CreateElement() never allows qualified name.
                        // I leave it as it is.
                        return new XmlElement (prefix != null ? prefix : String.Empty, localName, namespaceURI != null ? namespaceURI : String.Empty, this, false);
                }
 
+               internal XmlElement CreateElement (
+                       string prefix,
+                       string localName,
+                       string namespaceURI,
+                       bool nameAtomized)
+               {
+                       if ((localName == null) || (localName == String.Empty))
+                               throw new ArgumentException ("The local name for elements or attributes cannot be null or an empty string.");
+                       if (optimal_create_element)
+                               // LAMESPEC: MS.NET has a weird behavior that they can Load() from XmlTextReader 
+                               // whose Namespaces = false, but their CreateElement() never allows qualified name.
+                               // I leave it as it is.
+                               return new XmlElement (prefix != null ? prefix : String.Empty, localName, namespaceURI != null ? namespaceURI : String.Empty, this, nameAtomized);
+                       else
+                               return CreateElement (prefix, localName, namespaceURI);
+               }
+
                public virtual XmlEntityReference CreateEntityReference (string name)
                {
                        return new XmlEntityReference (name, this);
@@ -593,7 +638,7 @@ namespace System.Xml
                                return df;
 
                        case XmlNodeType.DocumentType:
-                               throw new XmlException ("DocumentType cannot be imported.");
+                               return ((XmlDocumentType) node).CloneNode (deep);
 
                        case XmlNodeType.Element:
                                XmlElement src = (XmlElement)node;
@@ -695,7 +740,7 @@ namespace System.Xml
                                                break;
                                        if (preserveWhitespace || n.NodeType != XmlNodeType.Whitespace)
                                                AppendChild (n, false);
-                               } while (true);
+                               } while (xmlReader.NodeType != XmlNodeType.EndElement);
 #if NET_2_0
                                if (xmlReader.Settings != null)
                                        schemas = xmlReader.Settings.Schemas;
@@ -710,7 +755,7 @@ namespace System.Xml
                        XmlTextReader xmlReader = new XmlTextReader (
                                xml,
                                XmlNodeType.Document,
-                               new XmlParserContext (NameTable, null, null, XmlSpace.None));
+                               new XmlParserContext (NameTable, new XmlNamespaceManager (NameTable), null, XmlSpace.None));
                        try {
                                xmlReader.XmlResolver = resolver;
                                Load (xmlReader);
@@ -783,10 +828,10 @@ 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, false, false); // different NameTable
+                       XmlAttribute attribute = CreateAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
 #if NET_2_0
                        if (reader.SchemaInfo != null)
-                               SchemaInfo = new XmlSchemaInfo (reader.SchemaInfo);
+                               SchemaInfo = reader.SchemaInfo;
 #endif
                        bool isDefault = reader.IsDefault;
 
@@ -837,7 +882,7 @@ namespace System.Xml
                        case ReadState.Initial:
 #if NET_2_0
                                if (reader.SchemaInfo != null)
-                                       this.SchemaInfo = new XmlSchemaInfo (reader.SchemaInfo);
+                                       SchemaInfo = reader.SchemaInfo;
 #endif
                                reader.Read ();
                                break;
@@ -865,10 +910,10 @@ namespace System.Xml
                                break;
 
                        case XmlNodeType.Element:
-                               XmlElement element = CreateElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                               XmlElement element = CreateElement (reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.NameTable == this.NameTable);
 #if NET_2_0
                                if (reader.SchemaInfo != null)
-                                       SchemaInfo = new XmlSchemaInfo (reader.SchemaInfo);
+                                       SchemaInfo = reader.SchemaInfo;
 #endif
                                element.IsEmpty = reader.IsEmptyElement;