2003-02-28 Alan Tam <Tam@SiuLung.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlWriter.cs
index e70e6869f7bfd4baa744c81eb0da27704b83e01c..0bd2412a08439e3bf306aba935e6e395f5056b79 100644 (file)
@@ -13,6 +13,13 @@ namespace System.Xml
 {
        public abstract class XmlWriter
        {
+               #region Fields
+
+               protected WriteState ws = WriteState.Start;
+               protected XmlNamespaceManager namespaceManager = new XmlNamespaceManager (new NameTable ());
+
+               #endregion
+
                #region Constructors
 
                protected XmlWriter () { }
@@ -37,28 +44,77 @@ namespace System.Xml
 
                public abstract string LookupPrefix (string ns);
 
-               [MonoTODO]
+               [MonoTODO("DTDs must be implemented to use 'defattr' parameter.")]
                public virtual void WriteAttributes (XmlReader reader, bool defattr)
                {
-                       throw new NotImplementedException ();
+                       if(reader == null)
+                               throw new ArgumentException("null XmlReader specified.", "reader");
+
+                       switch(reader.NodeType)
+                       {
+                               case XmlNodeType.XmlDeclaration:
+                                       // this method doesn't write "<?xml " and "?>", at least MS .NET Framework as yet.
+                                       XmlDeclaration decl = new XmlDeclaration("1.0", String.Empty, String.Empty, null);
+                                       decl.Value = reader.Value;
+                                       if(decl.Version != null && decl.Version != String.Empty) WriteAttributeString("version", decl.Version);
+                                       if(decl.Encoding != null && decl.Encoding != String.Empty) WriteAttributeString("encoding", decl.Encoding);
+                                       if(decl.Standalone != null && decl.Standalone != String.Empty) WriteAttributeString("standalone", decl.Standalone);
+                                       break;
+                               case XmlNodeType.Element:
+                                       while (reader.MoveToNextAttribute ()) 
+                                       {
+                                               WriteAttributeString(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
+                                       }
+                                       break;
+                               case XmlNodeType.Attribute:
+                                       do
+                                       {
+                                               WriteAttributeString(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
+                                       }
+                                       while (reader.MoveToNextAttribute ()) ;
+                                       break;
+                               default:
+                                       throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
+                       }
                }
 
-               [MonoTODO]
                public void WriteAttributeString (string localName, string value)
                {
-                       throw new NotImplementedException ();
+                       WriteAttributeString ("", localName, "", value);
                }
 
-               [MonoTODO]
                public void WriteAttributeString (string localName, string ns, string value)
                {
-                       throw new NotImplementedException ();
+                       WriteAttributeString ("", localName, ns, value);
                }
 
-               [MonoTODO]
                public void WriteAttributeString (string prefix, string localName, string ns, string value)
                {
-                       throw new NotImplementedException ();
+                       if ((prefix == "xmlns") || (localName == "xmlns"))
+                         {
+                               ns = value;
+                               
+                               if (prefix == "xmlns" && namespaceManager.HasNamespace (localName))
+                                       return;
+                               
+                               /* Users need to be able to re-declare the default namespace for subnodes
+                               else if (localName == "xmlns" && namespaceManager.HasNamespace (String.Empty))
+                                       return;
+                               */
+                         }
+                       
+                       WriteStartAttribute (prefix, localName, ns);
+                       WriteString (value);
+                       WriteEndAttribute ();
+
+                       if ((prefix == "xmlns") || (localName == "xmlns")) 
+                       {
+                               if (prefix == "xmlns")
+                                       namespaceManager.AddNamespace (localName, ns);
+                               else
+                                       namespaceManager.AddNamespace ("", ns);
+                       }
+                       
                }
 
                public abstract void WriteBase64 (byte[] buffer, int index, int count);
@@ -103,10 +159,61 @@ namespace System.Xml
 
                public abstract void WriteNmToken (string name);
 
-               [MonoTODO]
+               [MonoTODO("needs to test")]
                public virtual void WriteNode (XmlReader reader, bool defattr)
                {
-                       throw new NotImplementedException ();
+                       if (reader == null)
+                               throw new ArgumentException ();
+
+                       if (reader.ReadState == ReadState.Initial) {
+                               while (reader.Read ())
+                                       WriteNode (reader, defattr);
+                       }
+                       else {
+                               switch (reader.NodeType) {
+                               case XmlNodeType.Element:
+                                       WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                                       WriteAttributes (reader, defattr);
+                                       if (reader.IsEmptyElement)
+                                               WriteEndElement ();
+                                       break;
+                               case XmlNodeType.Attribute:
+                                       break;
+                               case XmlNodeType.Text:
+                                       WriteString (reader.Value);
+                                       break;
+                               case XmlNodeType.CDATA:
+                                       WriteCData (reader.Value);
+                                       break;
+                               case XmlNodeType.EntityReference:
+                                       WriteEntityRef (reader.Name);
+                                       break;
+                               case XmlNodeType.ProcessingInstruction:
+                                       WriteProcessingInstruction (reader.Name, reader.Value);
+                                       break;
+                               case XmlNodeType.Comment:
+                                       WriteComment (reader.Value);
+                                       break;
+                               case XmlNodeType.DocumentType:
+                                       WriteDocType (reader.Name,
+                                               reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
+                                       break;
+                               case XmlNodeType.SignificantWhitespace:
+                                       goto case XmlNodeType.Whitespace;
+                               case XmlNodeType.Whitespace:
+                                       WriteWhitespace (reader.Value);
+                                       break;
+                               case XmlNodeType.EndElement:
+                                       break;
+                               case XmlNodeType.EndEntity:
+                                       break;
+                               case XmlNodeType.XmlDeclaration:
+                                       WriteStartDocument (reader.GetAttribute  ("standalone").ToLower () == "yes");
+                                       break;
+                               default:
+                                       throw new NotImplementedException ();
+                               }
+                       }
                }
 
                public abstract void WriteProcessingInstruction (string name, string text);
@@ -117,10 +224,9 @@ namespace System.Xml
 
                public abstract void WriteRaw (char[] buffer, int index, int count);
 
-               [MonoTODO]
                public void WriteStartAttribute (string localName, string ns)
                {
-                       throw new NotImplementedException ();
+                       WriteStartAttribute (null, localName, ns);
                }
 
                public abstract void WriteStartAttribute (string prefix, string localName, string ns);
@@ -131,12 +237,12 @@ namespace System.Xml
 
                public void WriteStartElement (string localName)
                {
-                       WriteStartElement ("", localName, "");
+                       WriteStartElement (null, localName, null);
                }
 
                public void WriteStartElement (string localName, string ns)
                {
-                       WriteStartElement ("", localName, ns);
+                       WriteStartElement (null, localName, ns);
                }
 
                public abstract void WriteStartElement (string prefix, string localName, string ns);