XmlWriter.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. //
  2. // System.Xml.XmlWriter
  3. //
  4. // Authors:
  5. // Kral Ferch <[email protected]>
  6. // Atsushi Enomoto <[email protected]>
  7. //
  8. // (C) 2002 Kral Ferch
  9. // (C) 2002-2003 Atsushi Enomoto
  10. //
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. using System;
  32. using System.IO;
  33. using System.Text;
  34. namespace System.Xml
  35. {
  36. #if NET_2_0
  37. public abstract class XmlWriter : IDisposable
  38. #else
  39. public abstract class XmlWriter
  40. #endif
  41. {
  42. #region Constructors
  43. protected XmlWriter () { }
  44. #endregion
  45. #region Properties
  46. public abstract WriteState WriteState { get; }
  47. public abstract string XmlLang { get; }
  48. public abstract XmlSpace XmlSpace { get; }
  49. #endregion
  50. #region Methods
  51. public abstract void Close ();
  52. #if NET_2_0
  53. [MonoTODO]
  54. public static XmlWriter Create (Stream stream)
  55. {
  56. throw new NotImplementedException ();
  57. }
  58. [MonoTODO]
  59. public static XmlWriter Create (string file)
  60. {
  61. throw new NotImplementedException ();
  62. }
  63. [MonoTODO]
  64. public static XmlWriter Create (TextWriter writer)
  65. {
  66. throw new NotImplementedException ();
  67. }
  68. [MonoTODO]
  69. public static XmlWriter Create (StringBuilder builder)
  70. {
  71. throw new NotImplementedException ();
  72. }
  73. [MonoTODO]
  74. public static XmlWriter Create (Stream stream, XmlWriterSettings settings)
  75. {
  76. throw new NotImplementedException ();
  77. }
  78. [MonoTODO]
  79. public static XmlWriter Create (string file, XmlWriterSettings settings)
  80. {
  81. throw new NotImplementedException ();
  82. }
  83. [MonoTODO]
  84. public static XmlWriter Create (StringBuilder builder, XmlWriterSettings settings)
  85. {
  86. throw new NotImplementedException ();
  87. }
  88. [MonoTODO]
  89. public static XmlWriter Create (TextWriter writer, XmlWriterSettings settings)
  90. {
  91. throw new NotImplementedException ();
  92. }
  93. [MonoTODO]
  94. public static XmlWriter Create (XmlWriter writer, XmlWriterSettings settings)
  95. {
  96. throw new NotImplementedException ();
  97. }
  98. [MonoTODO]
  99. public virtual void Dispose ()
  100. {
  101. Close ();
  102. }
  103. #endif
  104. public abstract void Flush ();
  105. public abstract string LookupPrefix (string ns);
  106. private void WriteAttribute (XmlReader reader, bool defattr)
  107. {
  108. if (!defattr && reader.IsDefault)
  109. return;
  110. WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
  111. while (reader.ReadAttributeValue ()) {
  112. switch (reader.NodeType) {
  113. case XmlNodeType.Text:
  114. WriteString (reader.Value);
  115. break;
  116. case XmlNodeType.EntityReference:
  117. WriteEntityRef (reader.Name);
  118. break;
  119. }
  120. }
  121. WriteEndAttribute ();
  122. }
  123. public virtual void WriteAttributes (XmlReader reader, bool defattr)
  124. {
  125. if(reader == null)
  126. throw new ArgumentException("null XmlReader specified.", "reader");
  127. switch (reader.NodeType) {
  128. case XmlNodeType.XmlDeclaration:
  129. WriteAttributeString ("version", reader ["version"]);
  130. if (reader ["encoding"] != null)
  131. WriteAttributeString ("encoding", reader ["encoding"]);
  132. if (reader ["standalone"] != null)
  133. WriteAttributeString ("standalone", reader ["standalone"]);
  134. break;
  135. case XmlNodeType.Element:
  136. if (reader.MoveToFirstAttribute ())
  137. goto case XmlNodeType.Attribute;
  138. break;
  139. case XmlNodeType.Attribute:
  140. do {
  141. WriteAttribute (reader, defattr);
  142. } while (reader.MoveToNextAttribute ());
  143. break;
  144. default:
  145. throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
  146. }
  147. }
  148. public void WriteAttributeString (string localName, string value)
  149. {
  150. WriteAttributeString ("", localName, null, value);
  151. }
  152. public void WriteAttributeString (string localName, string ns, string value)
  153. {
  154. WriteAttributeString ("", localName, ns, value);
  155. }
  156. public void WriteAttributeString (string prefix, string localName, string ns, string value)
  157. {
  158. // In MS.NET (1.0), this check is done *here*, not at WriteStartAttribute.
  159. // (XmlTextWriter.WriteStartAttribute("xmlns", "anyname", null) throws an exception.
  160. #if NET_1_0
  161. if ((prefix == "xmlns" || (prefix == "" && localName == "xmlns")) && ns == null)
  162. ns = "http://www.w3.org/2000/xmlns/";
  163. #endif
  164. WriteStartAttribute (prefix, localName, ns);
  165. WriteString (value);
  166. WriteEndAttribute ();
  167. }
  168. public abstract void WriteBase64 (byte[] buffer, int index, int count);
  169. public abstract void WriteBinHex (byte[] buffer, int index, int count);
  170. public abstract void WriteCData (string text);
  171. public abstract void WriteCharEntity (char ch);
  172. public abstract void WriteChars (char[] buffer, int index, int count);
  173. public abstract void WriteComment (string text);
  174. public abstract void WriteDocType (string name, string pubid, string sysid, string subset);
  175. public void WriteElementString (string localName, string value)
  176. {
  177. WriteStartElement(localName);
  178. WriteString(value);
  179. WriteEndElement();
  180. }
  181. public void WriteElementString (string localName, string ns, string value)
  182. {
  183. WriteStartElement(localName, ns);
  184. WriteString(value);
  185. WriteEndElement();
  186. }
  187. #if NET_2_0
  188. public void WriteElementString (string prefix, string localName, string ns, string value)
  189. {
  190. WriteStartElement(prefix, localName, ns);
  191. WriteString(value);
  192. WriteEndElement();
  193. }
  194. #endif
  195. public abstract void WriteEndAttribute ();
  196. public abstract void WriteEndDocument ();
  197. public abstract void WriteEndElement ();
  198. public abstract void WriteEntityRef (string name);
  199. public abstract void WriteFullEndElement ();
  200. public abstract void WriteName (string name);
  201. public abstract void WriteNmToken (string name);
  202. public virtual void WriteNode (XmlReader reader, bool defattr)
  203. {
  204. if (reader == null)
  205. throw new ArgumentException ();
  206. if (reader.ReadState == ReadState.Initial) {
  207. reader.Read ();
  208. do {
  209. WriteNode (reader, defattr);
  210. } while (!reader.EOF);
  211. return;
  212. }
  213. switch (reader.NodeType) {
  214. case XmlNodeType.Element:
  215. WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
  216. #if false
  217. WriteAttributes (reader, defattr);
  218. reader.MoveToElement ();
  219. #else
  220. // Well, I found that MS.NET took this way, since
  221. // there was a error-prone SgmlReader that fails
  222. // MoveToNextAttribute().
  223. if (reader.HasAttributes) {
  224. for (int i = 0; i < reader.AttributeCount; i++) {
  225. reader.MoveToAttribute (i);
  226. WriteAttribute (reader, defattr);
  227. }
  228. reader.MoveToElement ();
  229. }
  230. #endif
  231. if (reader.IsEmptyElement)
  232. WriteEndElement ();
  233. else {
  234. int depth = reader.Depth;
  235. reader.Read ();
  236. if (reader.NodeType != XmlNodeType.EndElement) {
  237. do {
  238. WriteNode (reader, defattr);
  239. } while (depth < reader.Depth);
  240. }
  241. WriteFullEndElement ();
  242. }
  243. break;
  244. // In case of XmlAttribute, don't proceed reader.
  245. case XmlNodeType.Attribute:
  246. return;
  247. case XmlNodeType.Text:
  248. WriteString (reader.Value);
  249. break;
  250. case XmlNodeType.CDATA:
  251. WriteCData (reader.Value);
  252. break;
  253. case XmlNodeType.EntityReference:
  254. WriteEntityRef (reader.Name);
  255. break;
  256. case XmlNodeType.XmlDeclaration:
  257. // LAMESPEC: It means that XmlWriter implementation _must not_ check
  258. // whether PI name is "xml" (it is XML error) or not.
  259. case XmlNodeType.ProcessingInstruction:
  260. WriteProcessingInstruction (reader.Name, reader.Value);
  261. break;
  262. case XmlNodeType.Comment:
  263. WriteComment (reader.Value);
  264. break;
  265. case XmlNodeType.DocumentType:
  266. WriteDocType (reader.Name,
  267. reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
  268. break;
  269. case XmlNodeType.SignificantWhitespace:
  270. goto case XmlNodeType.Whitespace;
  271. case XmlNodeType.Whitespace:
  272. WriteWhitespace (reader.Value);
  273. break;
  274. case XmlNodeType.EndElement:
  275. WriteFullEndElement ();
  276. break;
  277. case XmlNodeType.EndEntity:
  278. break;
  279. case XmlNodeType.None:
  280. return; // Do nothing, nor reporting errors.
  281. default:
  282. throw new XmlException ("Unexpected node " + reader.Name + " of type " + reader.NodeType);
  283. }
  284. reader.Read ();
  285. }
  286. public abstract void WriteProcessingInstruction (string name, string text);
  287. public abstract void WriteQualifiedName (string localName, string ns);
  288. public abstract void WriteRaw (string data);
  289. public abstract void WriteRaw (char[] buffer, int index, int count);
  290. public void WriteStartAttribute (string localName, string ns)
  291. {
  292. WriteStartAttribute (null, localName, ns);
  293. }
  294. public abstract void WriteStartAttribute (string prefix, string localName, string ns);
  295. public abstract void WriteStartDocument ();
  296. public abstract void WriteStartDocument (bool standalone);
  297. public void WriteStartElement (string localName)
  298. {
  299. WriteStartElement (null, localName, null);
  300. }
  301. public void WriteStartElement (string localName, string ns)
  302. {
  303. WriteStartElement (null, localName, ns);
  304. }
  305. public abstract void WriteStartElement (string prefix, string localName, string ns);
  306. public abstract void WriteString (string text);
  307. public abstract void WriteSurrogateCharEntity (char lowChar, char highChar);
  308. public abstract void WriteWhitespace (string ws);
  309. #endregion
  310. }
  311. }