XmlWriter.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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. using System;
  12. namespace System.Xml
  13. {
  14. public abstract class XmlWriter
  15. {
  16. #region Fields
  17. protected WriteState ws = WriteState.Start;
  18. #endregion
  19. #region Constructors
  20. protected XmlWriter () { }
  21. #endregion
  22. #region Properties
  23. public abstract WriteState WriteState { get; }
  24. public abstract string XmlLang { get; }
  25. public abstract XmlSpace XmlSpace { get; }
  26. #endregion
  27. #region Methods
  28. public abstract void Close ();
  29. public abstract void Flush ();
  30. public abstract string LookupPrefix (string ns);
  31. private void WriteAttribute (XmlReader reader, bool defattr)
  32. {
  33. if (!defattr && reader.IsDefault)
  34. return;
  35. WriteStartAttribute (reader.Prefix, reader.LocalName, reader.NamespaceURI);
  36. while (reader.ReadAttributeValue ()) {
  37. switch (reader.NodeType) {
  38. case XmlNodeType.Text:
  39. WriteString (reader.Value);
  40. break;
  41. case XmlNodeType.EntityReference:
  42. WriteEntityRef (reader.Name);
  43. break;
  44. }
  45. }
  46. WriteEndAttribute ();
  47. }
  48. public virtual void WriteAttributes (XmlReader reader, bool defattr)
  49. {
  50. if(reader == null)
  51. throw new ArgumentException("null XmlReader specified.", "reader");
  52. switch (reader.NodeType) {
  53. case XmlNodeType.XmlDeclaration:
  54. WriteAttributeString ("version", reader ["version"]);
  55. if (reader ["encoding"] != null)
  56. WriteAttributeString ("encoding", reader ["encoding"]);
  57. if (reader ["standalone"] != null)
  58. WriteAttributeString ("standalone", reader ["standalone"]);
  59. break;
  60. case XmlNodeType.Element:
  61. if (reader.MoveToFirstAttribute ())
  62. goto case XmlNodeType.Attribute;
  63. break;
  64. case XmlNodeType.Attribute:
  65. do {
  66. WriteAttribute (reader, defattr);
  67. } while (reader.MoveToNextAttribute ());
  68. break;
  69. default:
  70. throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
  71. }
  72. }
  73. public void WriteAttributeString (string localName, string value)
  74. {
  75. WriteAttributeString ("", localName, "", value);
  76. }
  77. public void WriteAttributeString (string localName, string ns, string value)
  78. {
  79. WriteAttributeString ("", localName, ns, value);
  80. }
  81. public void WriteAttributeString (string prefix, string localName, string ns, string value)
  82. {
  83. // In MS.NET (1.0), this check is done *here*, not at WriteStartAttribute.
  84. // (XmlTextWriter.WriteStartAttribute("xmlns", "anyname", null) throws an exception.
  85. if ((prefix == "xmlns") || (prefix == "" && localName == "xmlns"))
  86. if (ns == null)
  87. ns = "http://www.w3.org/2000/xmlns/";
  88. WriteStartAttribute (prefix, localName, ns);
  89. WriteString (value);
  90. WriteEndAttribute ();
  91. }
  92. public abstract void WriteBase64 (byte[] buffer, int index, int count);
  93. public abstract void WriteBinHex (byte[] buffer, int index, int count);
  94. public abstract void WriteCData (string text);
  95. public abstract void WriteCharEntity (char ch);
  96. public abstract void WriteChars (char[] buffer, int index, int count);
  97. public abstract void WriteComment (string text);
  98. public abstract void WriteDocType (string name, string pubid, string sysid, string subset);
  99. public void WriteElementString (string localName, string value)
  100. {
  101. WriteStartElement(localName);
  102. WriteString(value);
  103. WriteEndElement();
  104. }
  105. public void WriteElementString (string localName, string ns, string value)
  106. {
  107. WriteStartElement(localName, ns);
  108. WriteString(value);
  109. WriteEndElement();
  110. }
  111. public abstract void WriteEndAttribute ();
  112. public abstract void WriteEndDocument ();
  113. public abstract void WriteEndElement ();
  114. public abstract void WriteEntityRef (string name);
  115. public abstract void WriteFullEndElement ();
  116. public abstract void WriteName (string name);
  117. public abstract void WriteNmToken (string name);
  118. public virtual void WriteNode (XmlReader reader, bool defattr)
  119. {
  120. if (reader == null)
  121. throw new ArgumentException ();
  122. if (reader.ReadState == ReadState.Initial) {
  123. reader.Read ();
  124. do {
  125. WriteNode (reader, defattr);
  126. } while (!reader.EOF);
  127. return;
  128. }
  129. switch (reader.NodeType) {
  130. case XmlNodeType.Element:
  131. WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
  132. WriteAttributes (reader, defattr);
  133. reader.MoveToElement ();
  134. if (reader.IsEmptyElement)
  135. WriteEndElement ();
  136. else {
  137. int depth = reader.Depth;
  138. reader.Read ();
  139. do {
  140. WriteNode (reader, defattr);
  141. } while (depth < reader.Depth);
  142. WriteFullEndElement ();
  143. }
  144. break;
  145. // In case of XmlAttribute, don't proceed reader.
  146. case XmlNodeType.Attribute:
  147. return;
  148. case XmlNodeType.Text:
  149. WriteString (reader.Value);
  150. break;
  151. case XmlNodeType.CDATA:
  152. WriteCData (reader.Value);
  153. break;
  154. case XmlNodeType.EntityReference:
  155. WriteEntityRef (reader.Name);
  156. break;
  157. case XmlNodeType.ProcessingInstruction:
  158. WriteProcessingInstruction (reader.Name, reader.Value);
  159. break;
  160. case XmlNodeType.Comment:
  161. WriteComment (reader.Value);
  162. break;
  163. case XmlNodeType.DocumentType:
  164. WriteDocType (reader.Name,
  165. reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
  166. break;
  167. case XmlNodeType.SignificantWhitespace:
  168. goto case XmlNodeType.Whitespace;
  169. case XmlNodeType.Whitespace:
  170. WriteWhitespace (reader.Value);
  171. break;
  172. case XmlNodeType.EndElement:
  173. WriteFullEndElement ();
  174. break;
  175. case XmlNodeType.EndEntity:
  176. break;
  177. case XmlNodeType.XmlDeclaration:
  178. // FIXME: It seems different from MS way, but I have
  179. // no other idea to write start document statefully.
  180. string st = reader.GetAttribute ("standalone");
  181. if (st != null && st != String.Empty)
  182. WriteStartDocument (st.ToLower () == "yes");
  183. else
  184. WriteStartDocument ();
  185. break;
  186. case XmlNodeType.None:
  187. return; // Do nothing, nor reporting errors.
  188. default:
  189. throw new XmlException ("Unexpected node " + reader.Name + " of type " + reader.NodeType);
  190. }
  191. reader.Read ();
  192. }
  193. public abstract void WriteProcessingInstruction (string name, string text);
  194. public abstract void WriteQualifiedName (string localName, string ns);
  195. public abstract void WriteRaw (string data);
  196. public abstract void WriteRaw (char[] buffer, int index, int count);
  197. public void WriteStartAttribute (string localName, string ns)
  198. {
  199. WriteStartAttribute (null, localName, ns);
  200. }
  201. public abstract void WriteStartAttribute (string prefix, string localName, string ns);
  202. public abstract void WriteStartDocument ();
  203. public abstract void WriteStartDocument (bool standalone);
  204. public void WriteStartElement (string localName)
  205. {
  206. WriteStartElement (null, localName, null);
  207. }
  208. public void WriteStartElement (string localName, string ns)
  209. {
  210. WriteStartElement (null, localName, ns);
  211. }
  212. public abstract void WriteStartElement (string prefix, string localName, string ns);
  213. public abstract void WriteString (string text);
  214. public abstract void WriteSurrogateCharEntity (char lowChar, char highChar);
  215. public abstract void WriteWhitespace (string ws);
  216. #endregion
  217. }
  218. }