XmlSerializationWriter.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. //
  2. // System.Xml.Serialization.XmlSerializationWriter.cs
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. //
  10. using System;
  11. using System.Collections;
  12. using System.Text;
  13. using System.Xml;
  14. using System.Xml.Schema;
  15. namespace System.Xml.Serialization {
  16. public abstract class XmlSerializationWriter {
  17. #region Fields
  18. Hashtable references;
  19. int referenceCount;
  20. int qnameCount;
  21. ArrayList namespaces;
  22. XmlWriter writer;
  23. #endregion // Fields
  24. #region Constructors
  25. [MonoTODO]
  26. protected XmlSerializationWriter ()
  27. {
  28. qnameCount = 0;
  29. references = new Hashtable ();
  30. referenceCount = 0;
  31. }
  32. #endregion // Constructors
  33. #region Properties
  34. protected ArrayList Namespaces {
  35. get { return namespaces; }
  36. set { namespaces = value; }
  37. }
  38. protected XmlWriter Writer {
  39. get { return writer; }
  40. set { writer = value; }
  41. }
  42. #endregion // Properties
  43. #region Methods
  44. internal void Initialize (XmlWriter writer)
  45. {
  46. this.writer = writer;
  47. }
  48. internal abstract void WriteObject (object ob);
  49. [MonoTODO ("Implement")]
  50. protected void AddWriteCallback (Type type, string typeName, string typeNs, XmlSerializationWriteCallback callback)
  51. {
  52. throw new NotImplementedException ();
  53. }
  54. protected Exception CreateMismatchChoiceException (string value, string elementName, string enumValue)
  55. {
  56. string message = String.Format ("Value of {0} mismatches the type of {1}, you need to set it to {2}.", elementName, value, enumValue);
  57. return new InvalidOperationException (message);
  58. }
  59. protected Exception CreateUnknownAnyElementException (string name, string ns)
  60. {
  61. string message = String.Format ("The XML element named '{0}' from namespace '{1}' was not expected. The XML element name and namespace must match those provided via XmlAnyElementAttribute(s).", name, ns);
  62. return new InvalidOperationException (message);
  63. }
  64. protected Exception CreateUnknownTypeException (object o)
  65. {
  66. return CreateUnknownTypeException (o.GetType ());
  67. }
  68. protected Exception CreateUnknownTypeException (Type type)
  69. {
  70. string message = String.Format ("The type {0} may not be used in this context.", type);
  71. return new InvalidOperationException (message);
  72. }
  73. protected static string FromByteArrayBase64 (byte[] value)
  74. {
  75. return XmlCustomFormatter.FromByteArrayBase64 (value);
  76. }
  77. protected static string FromByteArrayHex (byte[] value)
  78. {
  79. return XmlCustomFormatter.FromByteArrayHex (value);
  80. }
  81. protected static string FromChar (char value)
  82. {
  83. return XmlCustomFormatter.FromChar (value);
  84. }
  85. protected static string FromDate (DateTime value)
  86. {
  87. return XmlCustomFormatter.FromDate (value);
  88. }
  89. protected static string FromDateTime (DateTime value)
  90. {
  91. return XmlCustomFormatter.FromDateTime (value);
  92. }
  93. protected static string FromEnum (long value, string[] values, long[] ids)
  94. {
  95. return XmlCustomFormatter.FromEnum (value, values, ids);
  96. }
  97. protected static string FromTime (DateTime value)
  98. {
  99. return XmlCustomFormatter.FromTime (value);
  100. }
  101. protected static string FromXmlName (string name)
  102. {
  103. return XmlCustomFormatter.FromXmlName (name);
  104. }
  105. protected static string FromXmlNCName (string ncName)
  106. {
  107. return XmlCustomFormatter.FromXmlNCName (ncName);
  108. }
  109. protected static string FromXmlNmToken (string nmToken)
  110. {
  111. return XmlCustomFormatter.FromXmlNmToken (nmToken);
  112. }
  113. protected static string FromXmlNmTokens (string nmTokens)
  114. {
  115. return XmlCustomFormatter.FromXmlNmTokens (nmTokens);
  116. }
  117. [MonoTODO ("Implement")]
  118. protected string FromXmlQualifiedName (XmlQualifiedName xmlQualifiedName)
  119. {
  120. return GetQualifiedName (xmlQualifiedName.Name, xmlQualifiedName.Namespace);
  121. }
  122. private string GetId (object o, bool addToReferencesList)
  123. {
  124. referenceCount += 1;
  125. string id = String.Format ("id{0}", referenceCount);
  126. if (addToReferencesList)
  127. references[o] = id;
  128. return id;
  129. }
  130. [MonoTODO ("Complete this list.")]
  131. private string GetPrimitiveTypeName (Type type)
  132. {
  133. if (type == typeof (string))
  134. return "string";
  135. if (type == typeof (bool))
  136. return "Boolean";
  137. if (type == typeof (float))
  138. return "float";
  139. if (type == typeof (double))
  140. return "double";
  141. if (type == typeof (XmlQualifiedName))
  142. return "QName";
  143. return String.Empty;
  144. }
  145. [MonoTODO ("Need to check for namespace conflicts before blindly allocating qN")]
  146. private string GetQualifiedName (string name, string ns)
  147. {
  148. qnameCount += 1;
  149. string prefix = String.Format ("q{0}", qnameCount);
  150. WriteAttribute ("xmlns", prefix, null, ns);
  151. return String.Format ("{0}:{1}", prefix, name);
  152. }
  153. protected abstract void InitCallbacks ();
  154. [MonoTODO ("Implement")]
  155. protected void TopLevelElement ()
  156. {
  157. throw new NotImplementedException ();
  158. }
  159. protected void WriteAttribute (string localName, byte[] value)
  160. {
  161. WriteAttribute (localName, String.Empty, value);
  162. }
  163. protected void WriteAttribute (string localName, string value)
  164. {
  165. WriteAttribute (String.Empty, localName, String.Empty, value);
  166. }
  167. protected void WriteAttribute (string localName, string ns, byte[] value)
  168. {
  169. if (value == null)
  170. return;
  171. Writer.WriteStartAttribute (localName, ns);
  172. WriteValue (value);
  173. Writer.WriteEndAttribute ();
  174. }
  175. protected void WriteAttribute (string localName, string ns, string value)
  176. {
  177. WriteAttribute (String.Empty, localName, ns, value);
  178. }
  179. protected void WriteAttribute (string prefix, string localName, string ns, string value)
  180. {
  181. if (value == null)
  182. return;
  183. Writer.WriteStartAttribute (prefix, localName, ns);
  184. WriteValue (value);
  185. Writer.WriteEndAttribute ();
  186. }
  187. [MonoTODO ("Implement")]
  188. protected void WriteElementEncoded (XmlNode node, string name, string ns, bool isNullable, bool any)
  189. {
  190. throw new NotImplementedException ();
  191. }
  192. [MonoTODO ("Implement")]
  193. protected void WriteElementLiteral (XmlNode node, string name, string ns, bool isNullable, bool any)
  194. {
  195. if (name != string.Empty)
  196. {
  197. if (node == null)
  198. {
  199. if (isNullable)
  200. WriteNullTagLiteral (name, ns);
  201. }
  202. else
  203. {
  204. Writer.WriteStartElement (name, ns);
  205. node.WriteTo (Writer);
  206. Writer.WriteEndElement ();
  207. }
  208. }
  209. else
  210. node.WriteTo (Writer);
  211. }
  212. protected void WriteElementQualifiedName (string localName, XmlQualifiedName value)
  213. {
  214. WriteElementQualifiedName (localName, String.Empty, value, null);
  215. }
  216. protected void WriteElementQualifiedName (string localName, string ns, XmlQualifiedName value)
  217. {
  218. WriteElementQualifiedName (localName, ns, value, null);
  219. }
  220. protected void WriteElementQualifiedName (string localName, XmlQualifiedName value, XmlQualifiedName xsiType)
  221. {
  222. WriteElementQualifiedName (localName, String.Empty, value, xsiType);
  223. }
  224. protected void WriteElementQualifiedName (string localName, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
  225. {
  226. localName = XmlCustomFormatter.FromXmlNCName (localName);
  227. WriteStartElement (localName, ns);
  228. Writer.WriteString (FromXmlQualifiedName (value));
  229. WriteEndElement ();
  230. }
  231. protected void WriteElementString (string localName, string value)
  232. {
  233. WriteElementString (localName, String.Empty, value, null);
  234. }
  235. protected void WriteElementString (string localName, string ns, string value)
  236. {
  237. WriteElementString (localName, ns, value, null);
  238. }
  239. protected void WriteElementString (string localName, string value, XmlQualifiedName xsiType)
  240. {
  241. WriteElementString (localName, String.Empty, value, xsiType);
  242. }
  243. [MonoTODO ("Implement")]
  244. protected void WriteElementString (string localName, string ns, string value, XmlQualifiedName xsiType)
  245. {
  246. if (value == null) return;
  247. if (xsiType != null) {
  248. localName = XmlCustomFormatter.FromXmlNCName (localName);
  249. WriteStartElement (localName, ns);
  250. WriteXsiType (xsiType.Name, xsiType.Namespace);
  251. Writer.WriteString (value);
  252. WriteEndElement ();
  253. }
  254. else
  255. Writer.WriteElementString (localName, ns, value);
  256. }
  257. protected void WriteElementStringRaw (string localName, byte[] value)
  258. {
  259. WriteElementStringRaw (localName, String.Empty, value, null);
  260. }
  261. protected void WriteElementStringRaw (string localName, string value)
  262. {
  263. WriteElementStringRaw (localName, String.Empty, value, null);
  264. }
  265. protected void WriteElementStringRaw (string localName, byte[] value, XmlQualifiedName xsiType)
  266. {
  267. WriteElementStringRaw (localName, String.Empty, value, xsiType);
  268. }
  269. protected void WriteElementStringRaw (string localName, string ns, byte[] value)
  270. {
  271. WriteElementStringRaw (localName, ns, value, null);
  272. }
  273. protected void WriteElementStringRaw (string localName, string ns, string value)
  274. {
  275. WriteElementStringRaw (localName, ns, value, null);
  276. }
  277. protected void WriteElementStringRaw (string localName, string value, XmlQualifiedName xsiType)
  278. {
  279. WriteElementStringRaw (localName, String.Empty, value, null);
  280. }
  281. [MonoTODO ("Implement")]
  282. protected void WriteElementStringRaw (string localName, string ns, byte[] value, XmlQualifiedName xsiType)
  283. {
  284. throw new NotImplementedException ();
  285. }
  286. [MonoTODO ("Implement")]
  287. protected void WriteElementStringRaw (string localName, string ns, string value, XmlQualifiedName xsiType)
  288. {
  289. localName = XmlCustomFormatter.FromXmlNCName (localName);
  290. WriteStartElement (localName, ns);
  291. if (xsiType != null)
  292. WriteXsiType (xsiType.Name, xsiType.Namespace);
  293. Writer.WriteRaw (value);
  294. WriteEndElement ();
  295. }
  296. protected void WriteEmptyTag (string name)
  297. {
  298. WriteEmptyTag (name, String.Empty);
  299. }
  300. [MonoTODO ("Verify")]
  301. protected void WriteEmptyTag (string name, string ns)
  302. {
  303. name = XmlCustomFormatter.FromXmlName (name);
  304. WriteStartElement (name, ns);
  305. WriteEndElement ();
  306. }
  307. protected void WriteEndElement ()
  308. {
  309. WriteEndElement (null);
  310. }
  311. [MonoTODO ("Implement")]
  312. protected void WriteEndElement (object o)
  313. {
  314. Writer.WriteEndElement ();
  315. }
  316. protected void WriteId (object o)
  317. {
  318. WriteAttribute ("id", GetId (o, true));
  319. }
  320. protected void WriteNamespaceDeclarations (XmlSerializerNamespaces ns)
  321. {
  322. if (ns == null)
  323. return;
  324. Hashtable tbl = ns.Namespaces;
  325. foreach (string key in tbl.Keys) {
  326. string val = tbl [key] as string;
  327. if (val == null)
  328. val = String.Empty;
  329. WriteAttribute ("xmlns", key, null, val);
  330. }
  331. }
  332. [MonoTODO ("Implement")]
  333. protected void WriteNullableQualifiedNameEncoded (string name, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
  334. {
  335. throw new NotImplementedException ();
  336. }
  337. [MonoTODO ("Implement")]
  338. protected void WriteNullableQualifiedNameLiteral (string name, string ns, XmlQualifiedName value)
  339. {
  340. throw new NotImplementedException ();
  341. }
  342. [MonoTODO ("Implement")]
  343. protected void WriteNullableStringEncoded (string name, string ns, string value, XmlQualifiedName xsiType)
  344. {
  345. throw new NotImplementedException ();
  346. }
  347. [MonoTODO ("Implement")]
  348. protected void WriteNullableStringEncodedRaw (string name, string ns, byte[] value, XmlQualifiedName xsiType)
  349. {
  350. throw new NotImplementedException ();
  351. }
  352. [MonoTODO ("Implement")]
  353. protected void WriteNullableStringEncodedRaw (string name, string ns, string value, XmlQualifiedName xsiType)
  354. {
  355. throw new NotImplementedException ();
  356. }
  357. [MonoTODO ("Implement")]
  358. protected void WriteNullableStringLiteral (string name, string ns, string value)
  359. {
  360. if (value != null)
  361. WriteElementString (name, ns, value, null);
  362. else
  363. {
  364. WriteStartElement (name, ns);
  365. WriteAttribute ("xsi","nil", ns, "true");
  366. WriteEndElement ();
  367. }
  368. }
  369. [MonoTODO ("Implement")]
  370. protected void WriteNullableStringLiteralRaw (string name, string ns, byte[] value)
  371. {
  372. throw new NotImplementedException ();
  373. }
  374. [MonoTODO ("Implement")]
  375. protected void WriteNullableStringLiteralRaw (string name, string ns, string value)
  376. {
  377. throw new NotImplementedException ();
  378. }
  379. protected void WriteNullTagEncoded (string name)
  380. {
  381. WriteNullTagEncoded (name, String.Empty);
  382. }
  383. [MonoTODO ("Implement")]
  384. protected void WriteNullTagEncoded (string name, string ns)
  385. {
  386. throw new NotImplementedException ();
  387. }
  388. protected void WriteNullTagLiteral (string name)
  389. {
  390. WriteNullTagLiteral (name, String.Empty);
  391. }
  392. protected void WriteNullTagLiteral (string name, string ns)
  393. {
  394. WriteStartElement (name, ns);
  395. WriteAttribute ("xsi","nil", XmlSchema.InstanceNamespace, "true");
  396. WriteEndElement ();
  397. }
  398. protected void WritePotentiallyReferencingElement (string n, string ns, object o)
  399. {
  400. WritePotentiallyReferencingElement (n, ns, o, null, false, false);
  401. }
  402. protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType)
  403. {
  404. WritePotentiallyReferencingElement (n, ns, o, ambientType, false, false);
  405. }
  406. protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType, bool suppressReference)
  407. {
  408. WritePotentiallyReferencingElement (n, ns, o, ambientType, suppressReference, false);
  409. }
  410. [MonoTODO ("Implement")]
  411. protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType, bool suppressReference, bool isNullable)
  412. {
  413. throw new NotImplementedException ();
  414. }
  415. [MonoTODO ("Implement")]
  416. protected void WriteReferencedElements ()
  417. {
  418. throw new NotImplementedException ();
  419. }
  420. protected void WriteReferencingElement (string n, string ns, object o)
  421. {
  422. WriteReferencingElement (n, ns, o, false);
  423. }
  424. [MonoTODO ("Implement")]
  425. protected void WriteReferencingElement (string n, string ns, object o, bool isNullable)
  426. {
  427. throw new NotImplementedException ();
  428. }
  429. [MonoTODO ("Implement")]
  430. protected void WriteSerializable (IXmlSerializable serializable, string name, string ns, bool isNullable)
  431. {
  432. throw new NotImplementedException ();
  433. }
  434. protected void WriteStartDocument ()
  435. {
  436. Writer.WriteStartDocument ();
  437. }
  438. protected void WriteStartElement (string name)
  439. {
  440. WriteStartElement (name, String.Empty, null, false);
  441. }
  442. protected void WriteStartElement (string name, string ns)
  443. {
  444. WriteStartElement (name, ns, null, false);
  445. }
  446. protected void WriteStartElement (string name, string ns, bool writePrefixed)
  447. {
  448. WriteStartElement (name, ns, null, writePrefixed);
  449. }
  450. protected void WriteStartElement (string name, string ns, object o)
  451. {
  452. WriteStartElement (name, ns, o, false);
  453. }
  454. [MonoTODO]
  455. protected void WriteStartElement (string name, string ns, object o, bool writePrefixed)
  456. {
  457. WriteState oldState = Writer.WriteState;
  458. if (writePrefixed) {
  459. name = XmlCustomFormatter.FromXmlName (name);
  460. Writer.WriteStartElement (String.Empty, name, ns);
  461. } else
  462. Writer.WriteStartElement (name, ns);
  463. if (oldState == WriteState.Prolog) {
  464. WriteAttribute ("xmlns","xsd",XmlSchema.Namespace,XmlSchema.Namespace);
  465. WriteAttribute ("xmlns","xsi",XmlSchema.InstanceNamespace,XmlSchema.InstanceNamespace);
  466. }
  467. }
  468. protected void WriteTypedPrimitive (string name, string ns, object o, bool xsiType)
  469. {
  470. string value;
  471. name = XmlCustomFormatter.FromXmlName (name);
  472. WriteStartElement (name, ns);
  473. if (o is XmlQualifiedName)
  474. value = FromXmlQualifiedName ((XmlQualifiedName) o);
  475. else
  476. value = o.ToString ();
  477. if (xsiType)
  478. WriteXsiType (GetPrimitiveTypeName (o.GetType ()), XmlSchema.Namespace);
  479. WriteValue (value);
  480. WriteEndElement ();
  481. }
  482. protected void WriteValue (byte[] value)
  483. {
  484. Writer.WriteBase64 (value, 0, value.Length);
  485. }
  486. protected void WriteValue (string value)
  487. {
  488. Writer.WriteString (value);
  489. }
  490. protected void WriteXmlAttribute (XmlNode node)
  491. {
  492. WriteXmlAttribute (node, null);
  493. }
  494. [MonoTODO ("Implement")]
  495. protected void WriteXmlAttribute (XmlNode node, object container)
  496. {
  497. if (!(node is XmlAttribute))
  498. throw new InvalidOperationException ("The node must be either type XmlAttribute or a derived type.");
  499. throw new NotImplementedException ();
  500. }
  501. protected void WriteXsiType (string name, string ns)
  502. {
  503. if (ns != null && ns != string.Empty)
  504. WriteAttribute ("xsi", "type", ns, GetQualifiedName (name, ns));
  505. else
  506. WriteAttribute ("xsi", "type", ns, name);
  507. }
  508. #endregion
  509. }
  510. }