xmltextwriter writestartdocument and writeendelement.
[mono.git] / mcs / class / System.XML / System.Xml / XmlTextWriter.cs
index 283d462ea1fd835704afc508584b14ca209d307f..38eaee5d5521b6163324f04ab240457a850a5ccf 100644 (file)
@@ -21,7 +21,9 @@ namespace System.Xml
                protected TextWriter w;
                protected bool openWriter = true;
                protected bool openStartElement;
-               protected Stack openElements = new Stack();
+               protected bool documentStarted = false;
+               protected Stack openElements = new Stack ();
+               protected XmlNamespaceManager namespaceManager = new XmlNamespaceManager (new NameTable ());
 
                #endregion
 
@@ -101,11 +103,13 @@ namespace System.Xml
 
                #region Methods
 
-               private void CheckOpenWriter ()
+               private void CheckState ()
                {
                        if (!openWriter) {
                                throw new InvalidOperationException ("The Writer is closed.");
                        }
+
+                       documentStarted = true;
                }
 
                public override void Close ()
@@ -159,7 +163,7 @@ namespace System.Xml
                                throw new ArgumentException ();
                        }
 
-                       CheckOpenWriter ();
+                       CheckState ();
                        CloseStartElement ();
 
                        w.Write("<![CDATA[{0}]]>", text);
@@ -183,7 +187,7 @@ namespace System.Xml
                                throw new ArgumentException ();
                        }
 
-                       CheckOpenWriter ();
+                       CheckState ();
                        CloseStartElement ();
 
                        w.Write ("<!--{0}-->", text);
@@ -209,6 +213,11 @@ namespace System.Xml
 
                public override void WriteEndElement ()
                {
+                       if (openElements.Count == 0)
+                               throw new InvalidOperationException("There was no XML start tag open.");
+
+                       CheckState ();
+
                        if (openStartElement) {
                                w.Write (" />");
                                openElements.Pop ();
@@ -216,6 +225,7 @@ namespace System.Xml
                        }
                        else {
                                w.Write ("</{0}>", openElements.Pop ());
+                               namespaceManager.PopScope();
                        }
                }
 
@@ -249,7 +259,7 @@ namespace System.Xml
                                throw new ArgumentException ();
                        }
 
-                       CheckOpenWriter ();
+                       CheckState ();
                        CloseStartElement ();
 
                        w.Write ("<?{0} {1}?>", name, text);
@@ -279,10 +289,15 @@ namespace System.Xml
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public override void WriteStartDocument ()
                {
-                       throw new NotImplementedException ();
+                       if (documentStarted == true) {
+                               throw new InvalidOperationException("WriteStartDocument should be the first call.");
+                       }
+
+                       CheckState ();
+
+                       w.Write("<?xml version=\"1.0\" encoding=\"" + w.Encoding.HeaderName + "\"?>");
                }
 
                [MonoTODO]
@@ -291,22 +306,54 @@ namespace System.Xml
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO("Not dealing with prefix and ns yet.")]
                public override void WriteStartElement (string prefix, string localName, string ns)
                {
-                       CheckOpenWriter ();
+                       if ((prefix != String.Empty) && (ns == String.Empty))
+                               throw new ArgumentException ("Cannot use a prefix with an empty namespace.");
+
+                       CheckState ();
                        CloseStartElement ();
-                       w.Write ("<{0}", localName);
-                       openElements.Push (localName);
+
+                       string formatXmlns = "";
+                       string formatPrefix = "";
+
+                       if (ns != String.Empty) 
+                       {
+                               string existingPrefix = namespaceManager.LookupPrefix (ns);
+
+                               if (prefix == String.Empty)
+                                       prefix = existingPrefix;
+
+                               if (prefix != existingPrefix)
+                                       formatXmlns = " xmlns:" + prefix + "=\"" + ns + "\"";
+                               else if (existingPrefix == String.Empty)
+                                       formatXmlns = " xmlns=\"" + ns + "\"";
+                       }
+                       else if ((prefix == String.Empty) && (namespaceManager.LookupNamespace(prefix) != String.Empty)) {
+                               formatXmlns = " xmlns=\"\"";
+                       }
+
+                       if (prefix != String.Empty) {
+                               formatPrefix = prefix + ":";
+                       }
+
+                       w.Write ("<{0}{1}{2}", formatPrefix, localName, formatXmlns);
+
+                       openElements.Push (formatPrefix + localName);
                        openStartElement = true;
+
+                       namespaceManager.PushScope ();
+                       namespaceManager.AddNamespace (prefix, ns);
                }
 
                [MonoTODO("Haven't done any entity replacements yet.")]
                public override void WriteString (string text)
                {
-                       CheckOpenWriter ();
-                       CloseStartElement ();
-                       w.Write (text);
+                       if (text != String.Empty) {
+                               CheckState ();
+                               CloseStartElement ();
+                               w.Write (text);
+                       }
                }
 
                [MonoTODO]