2003-10-25 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml / XmlWriter.cs
index fef9c142e340a3bea167ad3fb4d860eb6fd00de0..de6317e25bee8ae7dedef6ddefa96a48d730c138 100644 (file)
@@ -1,10 +1,12 @@
 //
-// System.Xml.XmlTextWriter
+// System.Xml.XmlWriter
 //
-// Author:
+// Authors:
 //   Kral Ferch <kral_ferch@hotmail.com>
+//   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
 //
 // (C) 2002 Kral Ferch
+// (C) 2002-2003 Atsushi Enomoto
 //
 
 using System;
@@ -13,13 +15,6 @@ 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 () { }
@@ -44,7 +39,25 @@ namespace System.Xml
 
                public abstract string LookupPrefix (string ns);
 
-               [MonoTODO("DTDs must be implemented to use 'defattr' parameter.")]
+               private void WriteAttribute (XmlReader reader, bool defattr)
+               {
+                       if (!defattr && reader.IsDefault)
+                               return;
+
+                       WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+                       while (reader.ReadAttributeValue ()) {
+                               switch (reader.NodeType) {
+                               case XmlNodeType.Text:
+                                       WriteString (reader.Value);
+                                       break;
+                               case XmlNodeType.EntityReference:
+                                       WriteEntityRef (reader.Name);
+                                       break;
+                               }
+                       }
+                       WriteEndAttribute ();
+               }
+
                public virtual void WriteAttributes (XmlReader reader, bool defattr)
                {
                        if(reader == null)
@@ -52,15 +65,11 @@ namespace System.Xml
 
                        switch (reader.NodeType) {
                        case XmlNodeType.XmlDeclaration:
-                               string val = reader ["version"];
-                               if (val != String.Empty)
-                                       WriteAttributeString ("version", val);
-                               val = reader ["encoding"];
-                               if (val != String.Empty)
-                                       WriteAttributeString ("encoding", val);
-                               val = reader ["standalone"];
-                               if(val != String.Empty)
-                                       WriteAttributeString ("standalone", val);
+                               WriteAttributeString ("version", reader ["version"]);
+                               if (reader ["encoding"] != null)
+                                       WriteAttributeString ("encoding", reader ["encoding"]);
+                               if (reader ["standalone"] != null)
+                                       WriteAttributeString ("standalone", reader ["standalone"]);
                                break;
                        case XmlNodeType.Element:
                                if (reader.MoveToFirstAttribute ())
@@ -68,8 +77,7 @@ namespace System.Xml
                                break;
                        case XmlNodeType.Attribute:
                                do {
-                                       // FIXME: use ReadAttributeValue () for strictly write EntityReference.
-                                       WriteAttributeString (reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
+                                       WriteAttribute (reader, defattr);
                                } while (reader.MoveToNextAttribute ());
                                break;
                        default:
@@ -89,31 +97,15 @@ namespace System.Xml
 
                public void WriteAttributeString (string prefix, string localName, string ns, string value)
                {
-                       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;
-                               */
-                         }
-                       
+                       // In MS.NET (1.0), this check is done *here*, not at WriteStartAttribute.
+                       // (XmlTextWriter.WriteStartAttribute("xmlns", "anyname", null) throws an exception.
+                       if ((prefix == "xmlns") || (prefix == "" && localName == "xmlns"))
+                               if (ns == null)
+                                       ns = "http://www.w3.org/2000/xmlns/";
+
                        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);
@@ -158,7 +150,6 @@ namespace System.Xml
 
                public abstract void WriteNmToken (string name);
 
-               [MonoTODO("needs to test")]
                public virtual void WriteNode (XmlReader reader, bool defattr)
                {
                        if (reader == null)
@@ -185,7 +176,7 @@ namespace System.Xml
                                        do {
                                                WriteNode (reader, defattr);
                                        } while (depth < reader.Depth);
-                                       WriteEndElement ();
+                                       WriteFullEndElement ();
                                }
                                break;
                        // In case of XmlAttribute, don't proceed reader.
@@ -200,6 +191,9 @@ namespace System.Xml
                        case XmlNodeType.EntityReference:
                                WriteEntityRef (reader.Name);
                                break;
+                       case XmlNodeType.XmlDeclaration:
+                               // LAMESPEC: It means that XmlWriter implementation _must not_ check
+                               // whether PI name is "xml" (it is XML error) or not.
                        case XmlNodeType.ProcessingInstruction:
                                WriteProcessingInstruction (reader.Name, reader.Value);
                                break;
@@ -216,19 +210,14 @@ namespace System.Xml
                                WriteWhitespace (reader.Value);
                                break;
                        case XmlNodeType.EndElement:
-                               WriteEndElement ();
+                               WriteFullEndElement ();
                                break;
                        case XmlNodeType.EndEntity:
                                break;
-                       case XmlNodeType.XmlDeclaration:
-                               string st = reader.GetAttribute ("standalone");
-                               if (st != String.Empty)
-                                        WriteStartDocument (st.ToLower () == "yes");
-                               else
-                                       WriteStartDocument ();
-                               break;
+                       case XmlNodeType.None:
+                               return; // Do nothing, nor reporting errors.
                        default:
-                               throw new NotImplementedException ();
+                               throw new XmlException ("Unexpected node " + reader.Name + " of type " + reader.NodeType);
                        }
                        reader.Read ();
                }