1 //
2 // ComplexDataStructure.cs
3 //
4 // Author:
5 //	Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // (C) 2004 Novell, Inc.
8 //
9 //
10 using System;
11 using System.IO;
12 using System.Xml;
13 using System.Xml.Schema;
14 using System.Xml.Serialization;
15 using System.Collections;
16 using System.ComponentModel;
17 using NUnit.Framework;
18 
19 namespace MonoTests.System.XmlSerialization
20 {
21 	[TestFixture]
22 	public class ComplexDataStructure
23 	{
24 		[Test]
25 		[NUnit.Framework.Category("NotDotNet")] // FDBK50639
WriteLiteral()26 		public void WriteLiteral ()
27 		{
28 			Test data = BuildTestObject ();
29 
30 			XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
31 			XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
32 			StringWriter sw = new StringWriter();
33 			ss.Serialize (sw,data,nams);
34 			string serialized = sw.ToString ();
35 			serialized = XmlSerializerTests.Infoset (serialized);
36 
37 			StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
38 			string expected = sr.ReadToEnd ();
39 			sr.Close ();
40 
41 			expected = XmlSerializerTests.Infoset (expected);
42 			Assert.AreEqual (expected, serialized);
43 		}
44 
45 		[Test]
46 		[NUnit.Framework.Category ("NotDotNet")] // MS.NET results in compilation error (probably it generates bogus source.)
47 		[NUnit.Framework.Category ("MobileNotWorking")]
ReadLiteral()48 		public void ReadLiteral ()
49 		{
50 			XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
51 			XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
52 
53 			StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
54 			Test data = (Test) ss.Deserialize (sr);
55 			sr.Close ();
56 
57 			CheckObjectContent (BuildTestObject(), data);
58 		}
59 
GetLiteralTypeMapping()60 		XmlTypeMapping GetLiteralTypeMapping ()
61 		{
62 			XmlRootAttribute root = new XmlRootAttribute("rootroot");
63 			Type[] types = new Type[] {typeof(UknTestPart), typeof(AnotherTestPart), typeof(DblStringContainer) };
64 			XmlReflectionImporter ri = new XmlReflectionImporter ();
65 			foreach (Type t in types) ri.IncludeType (t);
66 			return ri.ImportTypeMapping (typeof(Test), root);
67 		}
68 
GetEncodedTypeMapping()69 		XmlTypeMapping GetEncodedTypeMapping ()
70 		{
71 			SoapReflectionImporter sri = new SoapReflectionImporter ();
72 			sri.IncludeType (typeof(UknTestPart));
73 			sri.IncludeType (typeof(AnotherTestPart));
74 			sri.IncludeType (typeof(DblStringContainer));
75 			return sri.ImportTypeMapping (typeof(Test));
76 		}
77 
BuildTestObject()78 		Test BuildTestObject ()
79 		{
80 			XmlDocument doc = new XmlDocument();
81 
82 			Test t = new UknTestPart();
83 			t.a = 1;
84 			t.b = "hola";
85 			t.bbis = t.b;
86 			t.c = 44;
87 			t.parts = new TestPart[3];
88 			t.parts[0] = new TestPart();
89 			t.parts[0].name = "un";
90 			t.parts[0].bval = true;
91 			t.parts[1] = new TestPart();
92 			t.parts[1].name = "dos";
93 			t.parts[1].bval = false;
94 			t.parts[2] = t.parts[0];
95 			t.part = t.parts[1];
96 			t.strings = new string[] { "un", "dos", null, "tres" };
97 			t.ushorts = new ushort[] { 1,2,3 };
98 			t.ta = new TB();
99 			t.ta.extraTextNodes = new XmlNode[] { doc.CreateTextNode ("AA"), doc.CreateTextNode ("BB") };
100 
101 			t.tam2 = new TA[][][]
102 					{
103 						new TA[][] { new TA[] {new TA(), new TA()}, new TA[] {new TA(), new TA()}},
104 						new TA[][] { new TA[] {new TB(), new TA()}, new TA[] {new TB(), new TA()}},
105 						new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}}
106 					};
107 
108 			t.tam3 = t.tam2;
109 			t.flatParts = t.parts;
110 
111 			t.flatParts2 = new TA[] {new TA(), new TB(), null, new TB()};
112 
113 			t.anot = new AnotherTestPart ();
114 			((AnotherTestPart)t.anot).lo = 1234567890;
115 
116 			t.ob = t.parts[1];
117 			t.ob2 = t.parts[1];
118 
119 			XmlElement e1 = doc.CreateElement ("explicitElement");
120 			XmlElement e2 = doc.CreateElement ("subElement");
121 			e2.SetAttribute ("unAtrib","val");
122 			doc.AppendChild (e1);
123 			e1.AppendChild (e2);
124 
125 			t.oneElem = e1;
126 			t.oneElem2 = e1;
127 			t.someElems = new XmlNode[3];
128 			t.someElems[0] = e1;
129 			t.someElems[1] = null;
130 			t.someElems[2] = e2;
131 
132 			t.extraElems = new XmlElement[1];
133 			t.extraElems[0] = doc.CreateElement ("extra1");
134 			t.extraElems[0].SetAttribute ("val","1");
135 
136 			t.extraElems23 = new XmlElement[2];
137 			t.extraElems23[0] = doc.CreateElement ("extra2");
138 			t.extraElems23[0].SetAttribute ("val","2");
139 			t.extraElems23[1] = doc.CreateElement ("extra3");
140 			t.extraElems23[1].SetAttribute ("val","3");
141 
142 			t.extraElemsRest = doc.CreateElement ("extra4");
143 			t.extraElemsRest.SetAttribute ("val","4");
144 
145 			t.uktester = new UnknownAttributeTester();
146 			t.uktester.aa = "hihi";
147 
148 			t.uktester.extraAtts = new XmlAttribute[3];
149 			t.uktester.extraAtts[0] = doc.CreateAttribute ("extraAtt1");
150 			t.uktester.extraAtts[0].Value = "val1";
151 			t.uktester.extraAtts[1] = doc.CreateAttribute ("extraAtt2");
152 			t.uktester.extraAtts[1].Value = "val2";
153 			t.uktester.extraAtts[2] = doc.CreateAttribute ("extraAtt3");
154 			t.uktester.extraAtts[2].Value = "val3";
155 
156 			t.ob3 = 12345;
157 			t.ob4 = (float)54321.12;
158 
159 			t.op1 = option.AA;
160 			t.opArray = new option[] { option.CC, option.BB, option.AA };
161 			t.ukOpt = option.DD;
162 			t.opAtt = option.BB;
163 
164 			t.byteArray = new byte[] { 11,33,55,222 };
165 			t.byteByteArray = new byte[][] { t.byteArray, t.byteArray };
166 
167 			t.ttList = new ArrayList();
168 			t.ttList.Add ("two");
169 			t.ttList.Add ("strings");
170 			//			t.extraText = "Additional text";
171 
172 			t.RoList = new ArrayList ();
173 			t.RoList.Add (t.parts[0]);
174 			t.RoList.Add (t.parts[1]);
175 
176 /*			t.struc = new OneStruct();
177 			t.struc.aa = 776655;
178 			t.struc.cc = "this is a struct";
179 */
180 			t.multiList = new ArrayList[2];
181 			t.multiList[0] = new ArrayList ();
182 			t.multiList[0].Add (22);
183 			t.multiList[0].Add (33);
184 			t.multiList[1] = new ArrayList ();
185 			t.multiList[1].Add (888);
186 			t.multiList[1].Add (999);
187 
188 			// XmlSerializer does not deserialize default values explicitly.
189 			//t.defElem = "theDefValue";
190 			//t.defAttr = "theDefValue";
191 
192 			t.special = new CustomHashtable ();
193 			t.special.Add ("one","1");
194 			t.special.Add ("two","2");
195 			t.special.Add ("three","3");
196 
197 			t.attqname = new XmlQualifiedName ("thename","thenamespace");
198 
199 			DblStringContainer dbc = new DblStringContainer ();
200 			dbc.doublestring = new string [][] { null, new string[] {"hello"} };
201 			AnotherTestPart at = new AnotherTestPart ();
202 			at.lo = 567;
203 			dbc.at = at;
204 
205 			DblStringContainerAnm dbca = new DblStringContainerAnm ();
206 			dbca.at = dbc;
207 			t.dbscontainer = dbca;
208 
209 			return t;
210 		}
211 
CheckObjectContent(Test exp, Test t)212 		void CheckObjectContent (Test exp, Test t)
213 		{
214 			Assert.AreEqual (exp.a, t.a, "t.a");
215 			Assert.AreEqual (exp.b, t.b, "t.b");
216 			Assert.AreEqual (exp.bbis, t.bbis, "t.bbis");
217 			Assert.AreEqual (exp.c, t.c, "t.c");
218 
219 			Assert.IsNotNull (t.parts, "t.parts");
220 			CheckParts ("t.parts", exp.parts, t.parts);
221 
222 			TestPart.AssertEquals ("t.part", exp.part, t.part);
223 
224 			AssertionHelper.AssertEqualsArray ("t.strings", exp.strings, t.strings);
225 			AssertionHelper.AssertEqualsArray ("t.ushorts", exp.ushorts, t.ushorts);
226 
227 			TA.AssertEquals ("t.ta", exp.ta, t.ta);
228 
229 			Assert.IsNotNull (t.tam2, "t.tam2");
230 			CheckTaArray ("t.tam2", exp.tam2, t.tam2);
231 
232 			Assert.IsNotNull (t.tam3, "t.tam3");
233 			CheckTaArray ("t.tam3", exp.tam3, t.tam3);
234 
235 			Assert.IsNotNull (t.flatParts, "t.flatParts");
236 			CheckParts ("t.flatParts", exp.flatParts, t.flatParts);
237 
238 			// Null element is ignored
239 			Assert.IsNotNull (t.flatParts2, "t.flatParts2");
240 			Assert.AreEqual (3, t.flatParts2.Length, "t.flatParts2.Length");
241 			TA.AssertEquals ("t.flatParts2 0", exp.flatParts2[0], t.flatParts2[0]);
242 			TA.AssertEquals ("t.flatParts2 1", exp.flatParts2[1], t.flatParts2[1]);
243 			TA.AssertEquals ("t.flatParts2 2", exp.flatParts2[3], t.flatParts2[2]);
244 
245 			Assert.IsNotNull (t.anot, "t.anot");
246 			Assert.AreEqual (((AnotherTestPart)exp.anot).lo, ((AnotherTestPart)t.anot).lo, "t.anot.lo");
247 
248 			TestPart.AssertEquals ("t.ob", exp.ob as TestPart, t.ob as TestPart);
249 			TestPart.AssertEquals ("t.ob2", exp.ob2 as TestPart, t.ob2 as TestPart);
250 
251 			AssertionHelper.AssertEqualsXml ("t.oneElem", exp.oneElem, t.oneElem);
252 			AssertionHelper.AssertEqualsXml ("t.oneElem2", exp.oneElem2, t.oneElem2);
253 
254 			// One of the elements was null and it is ignored
255 			Assert.IsNotNull (t.someElems, "t.someElems");
256 			Assert.AreEqual (2, t.someElems.Length, "t.someElems.Length");
257 			AssertionHelper.AssertEqualsXml ("t.someElems[0]", exp.someElems[0], t.someElems[0]);
258 			AssertionHelper.AssertEqualsXml ("t.someElems[1]", exp.someElems[2], t.someElems[1]);
259 
260 			Assert.IsNotNull (t.extraElems, "t.extraElems");
261 			Assert.AreEqual (exp.extraElems.Length, t.extraElems.Length, "t.extraElems.Length");
262 			for (int n=0; n<exp.extraElems.Length; n++)
263 				AssertionHelper.AssertEqualsXml ("t.extraElems[" + n + "]", exp.extraElems[n], t.extraElems[n]);
264 
265 			Assert.IsNotNull (t.extraElems23, "t.extraElems23");
266 			Assert.AreEqual (exp.extraElems23.Length, t.extraElems23.Length, "t.extraElems23.Length");
267 			for (int n=0; n<t.extraElems23.Length; n++)
268 				AssertionHelper.AssertEqualsXml ("t.extraElems23[" + n + "]", exp.extraElems23[n], t.extraElems23[n]);
269 
270 			AssertionHelper.AssertEqualsXml ("t.extraElemsRest", exp.extraElemsRest, t.extraElemsRest);
271 
272 			UnknownAttributeTester.AssertEquals ("t.uktester", exp.uktester, t.uktester);
273 
274 			Assert.AreEqual (exp.ob3, t.ob3, "t.ob3");
275 			Assert.AreEqual (exp.ob4, t.ob4, "t.ob4");
276 			Assert.AreEqual (exp.op1, t.op1, "t.op1");
277 
278 			AssertionHelper.AssertEqualsArray ("t.opArray", exp.opArray, t.opArray);
279 
280 			Assert.AreEqual (exp.ukOpt, t.ukOpt, "t.ukOpt");
281 			Assert.AreEqual (exp.opAtt, t.opAtt, "t.opAtt");
282 
283 			AssertionHelper.AssertEqualsArray ("t.byteArray", exp.byteArray, t.byteArray);
284 			AssertionHelper.AssertEqualsArray ("t.byteByteArray", exp.byteByteArray, t.byteByteArray);
285 
286 			Assert.IsNotNull (t.ttList, "t.ttList");
287 			AssertionHelper.AssertEqualsArray ("t.ttList", exp.ttList.ToArray(), t.ttList.ToArray());
288 
289 			Assert.IsNotNull (t.RoList, "t.RoList");
290 //			Assert.AreEqual (exp.RoList.Count, t.RoList.Count, "t.RoList.Count");
291 			for (int n=0; n<t.RoList.Count; n++)
292 				TestPart.AssertEquals ("t.RoList " + n, (TestPart)exp.RoList[n], (TestPart)t.RoList[n]);
293 
294 			Assert.AreEqual (exp.struc.aa, t.struc.aa, "t.struc.aa");
295 			Assert.AreSame (exp.struc.cc, t.struc.cc, "t.struc.cc");
296 
297 			Assert.IsNull (t.multiList, "t.multiList");
298 //			Assert.AreEqual (exp.multiList.Length, t.multiList.Length, "t.multiList.Count");
299 //			for (int n=0; n<exp.multiList.Length; n++)
300 //				AssertionHelper.AssertEqualsArray ("t.multiList " + n, exp.multiList[n].ToArray(), t.multiList[n].ToArray());
301 
302 			Assert.AreEqual (exp.defElem, t.defElem, "t.defElem");
303 			Assert.AreEqual (exp.defAttr, t.defAttr, "t.defAttr");
304 
305 			CustomHashtable.AssertEquals ("t.special", exp.special, t.special);
306 
307 			Assert.AreEqual (exp.attqname, t.attqname, "t.attqname");
308 
309 			Assert.IsNull (t.dbscontainer, "t.dbscontainer");
310 //			DblStringContainer tdbca = t.dbscontainer.at as DblStringContainer;
311 //			DblStringContainer expdbca = exp.dbscontainer.at as DblStringContainer;
312 //			Assert.IsNotNull (tdbca, "t.dbscontainer.at");
313 
314 //			Assert.IsNotNull (tdbca, "t.dbscontainer.dbca");
315 //			AssertionHelper.AssertEqualsArray ("t.dbscontainer.at.doublestring", expdbca.doublestring, tdbca.doublestring);
316 
317 //			AnotherTestPart tat = tdbca.at as AnotherTestPart;
318 //			AnotherTestPart expat = expdbca.at as AnotherTestPart;
319 //			Assert.IsNotNull (tat, "t.dbscontainer.dbca.at");
320 //			Assert.AreEqual (expat.lo, tat.lo, "t.dbscontainer.dbca.at.lo");
321 		}
322 
CheckParts(string id, TestPart[] exp, TestPart[] parts)323 		void CheckParts (string id, TestPart[] exp, TestPart[] parts)
324 		{
325 			AssertionHelper.AssertType (id, exp, parts);
326 			Assert.AreEqual (exp.Length, parts.Length, id + " Len");
327 			for (int n=0; n<exp.Length; n++)
328 				TestPart.AssertEquals (id + "[" + n + "]", exp[n], parts[n]);
329 		}
330 
CheckTaArray(string id, TA[][][] exp, TA[][][] arr)331 		void CheckTaArray (string id, TA[][][] exp, TA[][][] arr)
332 		{
333 			AssertionHelper.AssertType (id, exp, arr);
334 			Assert.AreEqual (exp.Length, arr.Length, id + " Len");
335 			for (int n=0; n<exp.Length; n++)
336 			{
337 				TA[][] tar = arr[n];
338 				TA[][] expar = exp[n];
339 
340 				AssertionHelper.AssertType (id, expar, tar);
341 				Assert.AreEqual (expar.Length, tar.Length);
342 
343 				for (int m=0; m<expar.Length; m++)
344 				{
345 					TA[] tar2 = tar[m];
346 					TA[] expar2 = expar[m];
347 
348 					AssertionHelper.AssertType (id, expar2, tar2);
349 					Assert.AreEqual (expar2.Length, tar2.Length, id);
350 
351 					for (int i=0; i<expar2.Length; i++)
352 						TA.AssertEquals (id + "[" + n + "][" + m + "][" + i + "]", expar2[i], tar2[i]);
353 				}
354 			}
355 		}
356 	}
357 
358 	public class AssertionHelper
359 	{
AssertType(string id, object exp, object ob)360 		public static bool AssertType (string id, object exp, object ob)
361 		{
362 			if (exp == null) {
363 				Assert.IsNull (ob, id);
364 				return false;
365 			}
366 			else {
367 				Assert.IsNotNull (ob, id);
368 				Assert.AreEqual (exp.GetType(), ob.GetType(), id + " type");
369 				return true;
370 			}
371 		}
372 
AssertEqualsXml(string id, XmlNode exp, XmlNode ob)373 		public static void AssertEqualsXml (string id, XmlNode exp, XmlNode ob)
374 		{
375 			if (!AssertType (id, exp, ob)) return;
376 			Assert.AreEqual (XmlSerializerTests.Infoset (exp), XmlSerializerTests.Infoset (ob), id);
377 		}
378 
AssertEqualsArray(string id, Array exp, Array ob)379 		public static void AssertEqualsArray (string id, Array exp, Array ob)
380 		{
381 			if (!AssertType (id, exp, ob)) return;
382 			Assert.AreEqual (exp.GetLength(0), ob.GetLength(0), id + " Length");
383 			for (int n=0; n<exp.GetLength(0); n++) {
384 				object it = exp.GetValue(n);
385 				if (it is Array)
386 					AssertEqualsArray (id + "[" + n + "]", it as Array, ob.GetValue(n) as Array);
387 				else
388 					Assert.AreEqual (it, ob.GetValue(n), id + "[" + n + "]");
389 			}
390 		}
391 	}
392 
393 	[XmlType(TypeName="")]
394 	[XmlRoot(ElementName="aaaaaa",Namespace="")]
395 	[XmlInclude(typeof(UknTestPart))]
396 	[SoapInclude(typeof(UknTestPart))]
397 	public class Test
398 	{
399 		//		public option op;elem.SchemaTypeName
400 		public object anot;
401 
402 		[SoapElement(ElementName="suba")]
403 		[XmlElement(ElementName="suba",Namespace="kk")]
404 		public int a;
405 
406 		public string b;
407 		public string bbis;
408 
409 		[SoapAttribute]
410 		[XmlAttribute (Namespace="attribns")]
411 		public byte c;
412 
413 		[XmlElement(Namespace="oo")]
414 		public TestPart part;
415 
416 		public TA ta;
417 
418 		public TestPart[] parts;
419 
420 		[SoapElement(ElementName="multita")]
421 		[XmlArray(ElementName="multita")]
422 			//		[XmlArrayItem(ElementName="itema",NestingLevel=1)]
423 		[XmlArrayItem(ElementName="itema",Type=typeof(TA),NestingLevel=1)]
424 		[XmlArrayItem(ElementName="itemb",Type=typeof(TB),NestingLevel=1)]
425 		public TA[][] tam = new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}};
426 
427 //		[SoapElement(ElementName="multita2")]
428 		[SoapIgnore]
429 		[XmlArray(ElementName="multita2")]
430 		[XmlArrayItem(ElementName="data1",NestingLevel=0)]
431 
432 		[XmlArrayItem(ElementName="data2",NestingLevel=1,Namespace="da2")]
433 		[XmlArrayItem(ElementName="data3a",Type=typeof(TA),NestingLevel=2,Namespace="da3")]
434 		[XmlArrayItem(ElementName="data3b",Type=typeof(TB),NestingLevel=2,Namespace="da3")]
435 		public TA[][][] tam2;
436 
437 		[SoapIgnore]
438 		public TA[][][] tam3;
439 
440 		[SoapElement(IsNullable=true)]
441 		[XmlElement(IsNullable=true)]
442 		public string mayBeNull;
443 
444 		public string[] strings;
445 
446 		[XmlArray(Namespace="arrayNamespace")]
447 		public ushort[] ushorts;
448 
449 		[XmlElement]
450 		public TestPart[] flatParts;
451 
452 		[SoapElement (ElementName="flatTAs")]
453 		[XmlElement (ElementName="flatTAs")]
454 		public TA[] flatParts2;
455 
456 		public object ob;
457 
458 		[XmlElement (Namespace="uimp")]
459 		public object ob2;
460 
461 		public object ob3;
462 		public object ob4;
463 
464 		[SoapIgnore]
465 		public XmlElement oneElem;
466 
467 		[SoapIgnore]
468 		[XmlElement (ElementName="unElement", Namespace="elemns")]
469 		public XmlElement oneElem2;
470 
471 		[SoapIgnore]
472 		[XmlElement (ElementName="unsElements", Namespace="elemns")]
473 		public XmlNode[] someElems;
474 
475 		[SoapIgnore]
476 		[XmlAnyElement ("extra1")]
477 		public XmlElement[] extraElems;
478 
479 		[SoapIgnore]
480 		[XmlAnyElement ("extra2")]
481 		[XmlAnyElement ("extra3")]
482 		[XmlAnyElement ("extra3","nnn")]
483 		public XmlElement[] extraElems23;
484 
485 		[SoapIgnore]
486 		[XmlAnyElement]
487 		public XmlElement extraElemsRest;
488 
489 		public UnknownAttributeTester uktester;
490 
491 		public option op1;
492 		public option[] opArray;
493 		public object ukOpt;
494 
495 		[XmlAttribute]
496 		[SoapIgnore]
497 		public option opAtt;
498 
499 
500 		public byte[] byteArray;
501 		[SoapIgnore]
502 		public byte[][] byteByteArray;
503 
504 		[XmlElement(Type=typeof(string))]
505 		[XmlElement(ElementName="kk",Type=typeof(int))]
506 		public object[] tt = new object[] { "aa",22 };
507 
508 		public ArrayList ttList;
509 
510 		ArrayList roList;
511 		public ArrayList RoList
512 		{
513 			get { return roList; }
514 			set { roList = value; }
515 		}
516 
517 		[SoapIgnore]
518 		[XmlIgnore] // Causes NRE in System.Xml.Serialization.CodeGenerator.GetVariableType (System.Object var)
519 		public ArrayList[] multiList;
520 
521 		[SoapIgnore]
522 		[XmlIgnore]
523 		public OneStruct struc;
524 
525 		[DefaultValue("theDefValue")]
526 		public string defElem;
527 
528 		[XmlAttribute]
529 		[DefaultValue("theDefValue")]
530 		public string defAttr;
531 
532 		[XmlText (Type=typeof(string))]
533 		[XmlElement (Type=typeof(int))]
534 		public object[] xmltext = new object[] {"aa",33,"bb",776};
535 
536 		[SoapIgnore]
537 		public CustomHashtable special;
538 
539 		[XmlAttribute]
540 		public XmlQualifiedName attqname;
541 
542 		[XmlAttribute]
543 		public DateTime[] arrayAttribute;
544 
545 		[XmlArray (Namespace="mm")]
546 		public string[][] dummyStringArray = new string[][] {null,null};
547 
548 		[XmlElement (Namespace="mm")]
549 		public DblStringContainerAnm dbscontainer;
550 	}
551 
552 	public class DblStringContainerAnm
553 	{
554 		public object at;
555 	}
556 
557 	[XmlType(Namespace="mm")]
558 	public class DblStringContainer
559 	{
560 		[XmlArrayItem (NestingLevel=1, IsNullable=true)]
561 		public string [][] doublestring;
562 		public object at;
563 	}
564 
565 	[SoapType(TypeName="TC")]
566 	[XmlType(TypeName="TC")]
567 	[XmlInclude(typeof(TB))]
568 	[SoapInclude(typeof(TB))]
569 	public class TA
570 	{
571 		public int xx = 1;
572 
573 		[XmlText]
574 		[SoapIgnore]
575 		public XmlNode[] extraTextNodes;
576 
AssertEquals(string id, TA expected, TA ob)577 		public static void AssertEquals (string id, TA expected, TA ob)
578 		{
579 			if (!AssertionHelper.AssertType (id, expected, ob)) return;
580 			Assert.AreEqual (expected.xx, ob.xx, id + " xx");
581 			// TODO: extraTextNodes
582 		}
583 	}
584 
585 	public class TB: TA
586 	{
587 		public int yy = 2;
588 
AssertEquals(string id, TB expected, TB ob)589 		public static void AssertEquals (string id, TB expected, TB ob)
590 		{
591 			if (!AssertionHelper.AssertType (id, expected, ob)) return;
592 			Assert.AreEqual (expected.yy, ob.yy, id + " yy");
593 			TA.AssertEquals (id + " base", expected, ob);
594 		}
595 	}
596 
597 	public class UnknownAttributeTester
598 
599 	{
600 		[SoapAttribute]
601 		[XmlAttribute]
602 		public string aa;
603 
604 		[SoapIgnore]
605 		[XmlAnyAttribute]
606 		public XmlAttribute[] extraAtts;
607 
608 		//		[XmlText(Type=typeof(XmlNode))]
609 		//		public XmlNode extraText;
610 
AssertEquals(string id, UnknownAttributeTester exp, UnknownAttributeTester ob)611 		public static void AssertEquals (string id, UnknownAttributeTester exp, UnknownAttributeTester ob)
612 		{
613 			if (!AssertionHelper.AssertType (id, exp, ob)) return;
614 			Assert.AreEqual (exp.aa, ob.aa, id + " aa");
615 
616 			if (!AssertionHelper.AssertType (id + " extraAtts", exp.extraAtts, ob.extraAtts)) return;
617 
618 			int p = 0;
619 			for (int n=0; n<ob.extraAtts.Length; n++)
620 			{
621 				XmlAttribute at = ob.extraAtts [n];
622 				if (at.NamespaceURI == "http://www.w3.org/2000/xmlns/") continue;
623 				Assert.IsTrue (p < exp.extraAtts.Length, id + " extraAtts length");
624 				AssertionHelper.AssertEqualsXml (id + ".extraAtts " + n, exp.extraAtts [p], ob.extraAtts[n]);
625 				p++;
626 			}
627 		}
628 	}
629 
630 	[SoapType(TypeName="UnTestPart", Namespace="mm")]
631 	[XmlType(TypeName="UnTestPart", Namespace="mm")]
632 	public class TestPart
633 	{
634 		public string name;
635 		public bool bval;
636 
AssertEquals(string id, TestPart expected, TestPart ob)637 		public static void AssertEquals (string id, TestPart expected, TestPart ob)
638 		{
639 			if (!AssertionHelper.AssertType (id, expected, ob)) return;
640 			Assert.AreEqual (expected.name, ob.name, id + " name");
641 			Assert.AreEqual (expected.bval, ob.bval, id + " bval");
642 		}
643 	}
644 
645 	[SoapType(Namespace="mm")]
646 	[XmlType(Namespace="mm")]
647 	public class AnotherTestPart
648 	{
649 		[XmlText]
650 		public long lo;
651 	}
652 
653 	public class UknTestPart : Test
654 	{
655 		[XmlElement(IsNullable=true)]
656 		public string uname;
657 		public bool uval;
658 	}
659 
660 	public struct OneStruct
661 	{
662 		public int aa;
663 		public string cc;
664 	}
665 
666 //	[XmlType(Namespace="enum_namespace")]
667 	public enum option
668 	{
669 		AA,
670 		[SoapEnum(Name="xmlBB")]
671 		[XmlEnum(Name="xmlBB")]
672 		BB,
673 		CC,
674 		DD
675 	}
676 
677 	public class CustomHashtable : IXmlSerializable
678 	{
679 		Hashtable data = new Hashtable ();
680 
Add(string key, string value)681 		public void Add (string key, string value)
682 		{
683 			data.Add (key, value);
684 		}
685 
AssertEquals(string id, CustomHashtable exp, CustomHashtable ob)686 		public static void AssertEquals (string id, CustomHashtable exp, CustomHashtable ob)
687 		{
688 			if (!AssertionHelper.AssertType (id, exp, ob)) return;
689 			if (!AssertionHelper.AssertType (id, exp.data, ob.data)) return;
690 
691 			Assert.AreEqual (exp.data.Count, ob.data.Count, id + " data Count");
692 
693 			foreach (DictionaryEntry entry in exp.data)
694 				Assert.AreEqual (entry.Value, ob.data[entry.Key]);
695 		}
696 
ReadXml(XmlReader reader)697 		public void ReadXml (XmlReader reader)
698 		{
699 			// Read the element enclosing the object
700 			reader.ReadStartElement();
701 			reader.MoveToContent ();
702 
703 			// Reads the "data" element
704 			reader.ReadStartElement();
705 			reader.MoveToContent ();
706 			while (reader.NodeType != XmlNodeType.EndElement)
707 			{
708 				if (reader.NodeType == XmlNodeType.Element)
709 				{
710 					string key = reader.LocalName;
711 					data [key] = reader.ReadElementString ();
712 				}
713 				else
714 					reader.Skip ();
715 				reader.MoveToContent ();
716 			}
717 
718 			reader.ReadEndElement ();
719 		}
720 
WriteXml(XmlWriter writer)721 		public void WriteXml (XmlWriter writer)
722 		{
723 			writer.WriteStartElement ("data");
724 			foreach (DictionaryEntry entry in data)
725 			{
726 				writer.WriteElementString ((string)entry.Key, (string)entry.Value);
727 			}
728 			writer.WriteEndElement ();
729 		}
730 
GetSchema()731 		public XmlSchema GetSchema ()
732 		{
733 			XmlSchema s = new XmlSchema ();
734 			s.TargetNamespace = "http://www.go-mono.org/schemas";
735 			s.Id = "monoschema";
736 			XmlSchemaElement e = new XmlSchemaElement ();
737 			e.Name = "data";
738 			s.Items.Add (e);
739 			XmlSchemaComplexType cs = new XmlSchemaComplexType ();
740 			XmlSchemaSequence seq = new XmlSchemaSequence ();
741 			XmlSchemaAny any = new XmlSchemaAny ();
742 			any.MinOccurs = 0;
743 			any.MaxOccurs = decimal.MaxValue;
744 			seq.Items.Add (any);
745 			cs.Particle = seq;
746 			e.SchemaType = cs;
747 			return s;
748 		}
749 	}
750 }
751