2002-12-28 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml / XmlDeclaration.cs
index 91b9e5d5a66558b0f0f8430986cd9cd5e00371d4..c34df121227c358b30325be58be625753af47d47 100644 (file)
-using System;\r
-\r
-namespace System.Xml\r
-{\r
-       /// <summary>\r
-       /// \r
-       /// </summary>\r
-       public class XmlDeclaration : XmlNode\r
-       {\r
-               // Private data members\r
-               private string Fencoding = "UTF-8";\r
-               bool Fstandalone;\r
-\r
-               // public properties\r
-               /// <summary>\r
-               /// Get/Set the encoding used for the document\r
-               /// Typical values are "UTF-8", "UTF-16", "ISO-8859-nn" (where n is 0-9).\r
-               /// If not defined, "UTF-8" is assumed.\r
-               /// encoding is not case sensitive.\r
-               /// </summary>\r
-               public string Encoding \r
-               {\r
-                       get\r
-                       {\r
-                               return Fencoding;\r
-                       }\r
-\r
-                       set\r
-                       {\r
-                               string val = value.ToUpper();\r
-\r
-                               if ( (val == "UTF-8") | ( val == "UTF-16") )\r
-                               {\r
-                                       Fencoding = value;\r
-                                       return;\r
-                               }\r
-                               else\r
-                               {\r
-                                       if ( ( val.StartsWith( "ISO-8859-" ) ) & (val.Length == 10) )\r
-                                       {\r
-                                               try\r
-                                               {\r
-                                                       int code = System.Convert.ToInt32( val.Substring(9,1) );\r
-                                                       Fencoding = value;\r
-                                               }\r
-                                               catch\r
-                                               {\r
-                                                       throw new NotImplementedException("Encoding " + value + " is not supported");\r
-                                               }\r
-\r
-                                       }\r
-\r
-                                       \r
-                               }\r
-                       }\r
-               }\r
-               \r
-               /// <summary>\r
-               /// Get the local name of the declaration.  Returns "xml"\r
-               /// </summary>\r
-               public override string LocalName \r
-               {\r
-                       get\r
-                       {\r
-                               return "xml";\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get the name of the node.  For XmlDeclaration, returns "xml".\r
-               /// </summary>\r
-               public override string Name \r
-               {\r
-                       get\r
-                       {\r
-                               return "xml";\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Return the node type.  For XmlDeclaration, returns XmlNodeType.XmlDeclaration.\r
-               /// </summary>\r
-               public override XmlNodeType NodeType \r
-               {\r
-                       get\r
-                       {\r
-                               return XmlNodeType.XmlDeclaration;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get/Set the value of the standalone attribute.\r
-               /// "yes" => no external DTD required.\r
-               /// "no" => external data sources required.\r
-               /// Silently fails if Set to invalid value.\r
-               /// Not case sensitive.\r
-               /// </summary>\r
-               public string Standalone {\r
-                       get\r
-                       {\r
-                               if (Fstandalone) \r
-                                       return "yes";\r
-                               else\r
-                                       return "no";\r
-                       }\r
-\r
-                       set\r
-                       {\r
-                               if (value.ToUpper() == "YES")\r
-                                       Fstandalone = true;\r
-                               if (value.ToUpper() == "NO")\r
-                                       Fstandalone = false;\r
-                       }\r
-               }\r
-\r
-               /// <summary>\r
-               /// Get the xml version of the file.  Returns "1.0"\r
-               /// </summary>\r
-               public string Version \r
-               {\r
-                       get\r
-                       {\r
-                               return "1.0";\r
-                       }\r
-               }\r
-\r
-               // Public Methods\r
-               /// <summary>\r
-               /// Overriden.  Returns a cloned version of this node.\r
-               /// Serves as a copy constructor.  Duplicate node has no parent.\r
-               /// </summary>\r
-               /// <param name="deep">Create deep copy.  N/A for XmlDeclaration.</param>\r
-               /// <returns>Cloned node.</returns>\r
-               public override XmlNode CloneNode(bool deep)\r
-               {\r
-                       // TODO - implement XmlDeclration.CloneNode()\r
-                       throw new NotImplementedException("XmlDeclration.CloneNode() not implemented");\r
-               }\r
-\r
-               /// <summary>\r
-               /// Save the children of this node to the passed XmlWriter.  Since an XmlDeclaration has \r
-               /// no children, this call has no effect.\r
-               /// </summary>\r
-               /// <param name="w"></param>\r
-               public override void WriteContentTo(XmlWriter w)\r
-               {\r
-                       // Nothing to do - no children.\r
-               }\r
-\r
-               /// <summary>\r
-               /// Saves the node to the specified XmlWriter\r
-               /// </summary>\r
-               /// <param name="w">XmlWriter to writ to.</param>\r
-               public override void WriteTo(XmlWriter w)\r
-               {\r
-                       // TODO - implement XmlDeclration.WriteTo()\r
-                       throw new NotImplementedException("XmlDeclaration.WriteTo() not implemented");\r
-               }\r
-\r
-               // Constructors\r
-               internal XmlDeclaration( XmlDocument aOwnerDoc) : base(aOwnerDoc)\r
-               {\r
-               }\r
-       }\r
-}\r
+//
+// System.Xml.XmlDeclaration
+//
+// Author:
+//     Duncan Mak  (duncan@ximian.com)
+//
+// (C) Ximian, Inc.
+
+using System;
+using System.Xml;
+using System.Text.RegularExpressions;
+
+namespace System.Xml
+{
+       public class XmlDeclaration : XmlLinkedNode
+       {
+               string encoding = "UTF-8"; // defaults to UTF-8
+               string standalone;
+               string version;
+
+               protected internal XmlDeclaration (string version, string encoding,
+                                                  string standalone, XmlDocument doc)
+                       : base (doc)
+               {
+                       if (encoding == null)
+                               encoding = "";
+
+                       if (standalone == null)
+                               standalone = "";
+
+                       this.version = version;
+                       this.encoding = encoding;
+                       this.standalone = standalone;
+               }
+
+               public string Encoding  {
+                       get { return encoding; } 
+                       set { encoding = (value == null) ? String.Empty : value; }
+               }
+
+               public override string InnerText {
+                       get { return Value; }
+                       set { ParseInput (value); }
+               }
+               
+               public override string LocalName {
+                       get { return "xml"; }
+               }
+
+               public override string Name {
+                       get { return "xml"; }
+               }
+
+               public override XmlNodeType NodeType {
+                       get { return XmlNodeType.XmlDeclaration; }
+               }
+
+               public string Standalone {
+                       get { return standalone; }
+                       set {
+                               if(value != null)
+                               {
+                                       if (value.ToUpper() == "YES")
+                                               standalone = "yes";
+                                       if (value.ToUpper() == "NO")
+                                               standalone = "no";
+                               }
+                               else
+                                       standalone = String.Empty;
+                       }
+               }
+
+               public override string Value {
+                       get {
+                               string formatEncoding = "";
+                               string formatStandalone = "";
+
+                               if (encoding != String.Empty)
+                                       formatEncoding = String.Format (" encoding=\"{0}\"", encoding);
+
+                               if (standalone != String.Empty)
+                                       formatStandalone = String.Format (" standalone=\"{0}\"", standalone);
+
+                               return String.Format ("version=\"{0}\"{1}{2}", Version, formatEncoding, formatStandalone);
+                       }
+                       set { ParseInput (value); }
+               }
+
+               public string Version {
+                       get { return version; }
+               }
+
+               public override XmlNode CloneNode (bool deep)
+               {
+                       return new XmlDeclaration (Version, Encoding, standalone, OwnerDocument);
+               }
+
+               public override void WriteContentTo (XmlWriter w) {}
+
+               public override void WriteTo (XmlWriter w)
+               {
+                       // This doesn't seem to match up very well with w.WriteStartDocument()
+                       // so writing out custom here.
+                       w.WriteRaw (String.Format ("<?xml {0}?>", Value));
+               }
+
+               void ParseInput (string input)
+               {
+//                     Encoding = input.Split (new char [] { ' ' }) [1].Split (new char [] { '=' }) [1];
+//                     Standalone = input.Split (new char [] { ' ' }) [2].Split (new char [] { '=' }) [1];
+                       Match m = XmlDeclRegex.Match(input);
+                       if(!m.Success)
+                               throw new XmlException("illegal XML declaration format.");
+//                     Version = m.Result("${ver}");
+                       Encoding = m.Result("${enc}");
+                       Standalone = m.Result("${sta}");
+               }
+
+               // This regular expression matches XMLDecl of XML specification BNF[23]
+               static Regex xmlDeclRegex;
+               Regex XmlDeclRegex \r
+               {
+                       get \r
+                       {
+                               if(xmlDeclRegex == null) xmlDeclRegex = new Regex(allMatch, RegexOptions.Compiled);
+                               return xmlDeclRegex;
+                       }
+               }
+
+               // This code makes some loss, but you may understand a bit easily.
+               const string verMatch = "\\s*version\\s*=\\s*(\\'(?<ver>.*?)\\'|\\\"(?<ver>.*?)\")";
+               const string encMatch = "\\s*encoding\\s*=\\s*(\\'(?<enc>.*?)\\'|\\\"(?<enc>.*?)\")";
+               const string staMatch = "\\s*standalone\\s*=\\s*(\\'(?<sta>.*?)\\'|\\\"(?<sta>.*?)\")";
+               const string allMatch = verMatch + "(" + encMatch + ")?(" + staMatch + ")?";
+       }
+}