2 // ComplexDataStructure.cs
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // (C) 2004 Novell, Inc.
13 using System.Xml.Schema;
14 using System.Xml.Serialization;
15 using System.Collections;
16 using System.ComponentModel;
17 using NUnit.Framework;
19 namespace MonoTests.System.XmlSerialization
22 public class ComplexDataStructure: Assertion
25 [NUnit.Framework.Category("NotDotNet")] // FDBK50639
26 public void WriteLiteral ()
28 Test data = BuildTestObject ();
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);
37 StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
38 string expected = sr.ReadToEnd ();
41 expected = XmlSerializerTests.Infoset (expected);
42 AssertEquals (expected, serialized);
46 [NUnit.Framework.Category("NotDotNet")]
47 public void ReadLiteral ()
49 XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
50 XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
52 StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
53 Test data = (Test) ss.Deserialize (sr);
56 CheckObjectContent (BuildTestObject(), data);
59 XmlTypeMapping GetLiteralTypeMapping ()
61 XmlRootAttribute root = new XmlRootAttribute("rootroot");
62 Type[] types = new Type[] {typeof(UknTestPart), typeof(AnotherTestPart), typeof(DblStringContainer) };
63 XmlReflectionImporter ri = new XmlReflectionImporter ();
64 foreach (Type t in types) ri.IncludeType (t);
65 return ri.ImportTypeMapping (typeof(Test), root);
68 XmlTypeMapping GetEncodedTypeMapping ()
70 SoapReflectionImporter sri = new SoapReflectionImporter ();
71 sri.IncludeType (typeof(UknTestPart));
72 sri.IncludeType (typeof(AnotherTestPart));
73 sri.IncludeType (typeof(DblStringContainer));
74 return sri.ImportTypeMapping (typeof(Test));
77 Test BuildTestObject ()
79 XmlDocument doc = new XmlDocument();
81 Test t = new UknTestPart();
86 t.parts = new TestPart[3];
87 t.parts[0] = new TestPart();
88 t.parts[0].name = "un";
89 t.parts[0].bval = true;
90 t.parts[1] = new TestPart();
91 t.parts[1].name = "dos";
92 t.parts[1].bval = false;
93 t.parts[2] = t.parts[0];
95 t.strings = new string[] { "un", "dos", null, "tres" };
96 t.ushorts = new ushort[] { 1,2,3 };
98 t.ta.extraTextNodes = new XmlNode[] { doc.CreateTextNode ("AA"), doc.CreateTextNode ("BB") };
100 t.tam2 = new TA[][][]
102 new TA[][] { new TA[] {new TA(), new TA()}, new TA[] {new TA(), new TA()}},
103 new TA[][] { new TA[] {new TB(), new TA()}, new TA[] {new TB(), new TA()}},
104 new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}}
108 t.flatParts = t.parts;
110 t.flatParts2 = new TA[] {new TA(), new TB(), null, new TB()};
112 t.anot = new AnotherTestPart ();
113 ((AnotherTestPart)t.anot).lo = 1234567890;
118 XmlElement e1 = doc.CreateElement ("explicitElement");
119 XmlElement e2 = doc.CreateElement ("subElement");
120 e2.SetAttribute ("unAtrib","val");
121 doc.AppendChild (e1);
126 t.someElems = new XmlNode[3];
128 t.someElems[1] = null;
131 t.extraElems = new XmlElement[1];
132 t.extraElems[0] = doc.CreateElement ("extra1");
133 t.extraElems[0].SetAttribute ("val","1");
135 t.extraElems23 = new XmlElement[2];
136 t.extraElems23[0] = doc.CreateElement ("extra2");
137 t.extraElems23[0].SetAttribute ("val","2");
138 t.extraElems23[1] = doc.CreateElement ("extra3");
139 t.extraElems23[1].SetAttribute ("val","3");
141 t.extraElemsRest = doc.CreateElement ("extra4");
142 t.extraElemsRest.SetAttribute ("val","4");
144 t.uktester = new UnknownAttributeTester();
145 t.uktester.aa = "hihi";
147 t.uktester.extraAtts = new XmlAttribute[3];
148 t.uktester.extraAtts[0] = doc.CreateAttribute ("extraAtt1");
149 t.uktester.extraAtts[0].Value = "val1";
150 t.uktester.extraAtts[1] = doc.CreateAttribute ("extraAtt2");
151 t.uktester.extraAtts[1].Value = "val2";
152 t.uktester.extraAtts[2] = doc.CreateAttribute ("extraAtt3");
153 t.uktester.extraAtts[2].Value = "val3";
156 t.ob4 = (float)54321.12;
159 t.opArray = new option[] { option.CC, option.BB, option.AA };
163 t.byteArray = new byte[] { 11,33,55,222 };
164 t.byteByteArray = new byte[][] { t.byteArray, t.byteArray };
166 t.ttList = new ArrayList();
167 t.ttList.Add ("two");
168 t.ttList.Add ("strings");
169 // t.extraText = "Additional text";
171 t.RoList = new ArrayList ();
172 t.RoList.Add (t.parts[0]);
173 t.RoList.Add (t.parts[1]);
175 /* t.struc = new OneStruct();
177 t.struc.cc = "this is a struct";
179 t.multiList = new ArrayList[2];
180 t.multiList[0] = new ArrayList ();
181 t.multiList[0].Add (22);
182 t.multiList[0].Add (33);
183 t.multiList[1] = new ArrayList ();
184 t.multiList[1].Add (888);
185 t.multiList[1].Add (999);
188 t.defElem = "theDefValue";
189 t.defAttr = "theDefValue";
191 t.special = new CustomHashtable ();
192 t.special.Add ("one","1");
193 t.special.Add ("two","2");
194 t.special.Add ("three","3");
196 t.attqname = new XmlQualifiedName ("thename","thenamespace");
198 DblStringContainer dbc = new DblStringContainer ();
199 dbc.doublestring = new string [][] { null, new string[] {"hello"} };
200 AnotherTestPart at = new AnotherTestPart ();
204 DblStringContainerAnm dbca = new DblStringContainerAnm ();
206 t.dbscontainer = dbca;
211 void CheckObjectContent (Test exp, Test t)
213 AssertEquals ("t.a", exp.a, t.a);
214 AssertEquals ("t.b", exp.b, t.b);
215 AssertEquals ("t.bbis", exp.bbis, t.bbis);
216 AssertEquals ("t.c", exp.c, t.c);
218 AssertNotNull ("t.parts", t.parts);
219 CheckParts ("t.parts", exp.parts, t.parts);
221 TestPart.AssertEquals ("t.part", exp.part, t.part);
223 AssertionHelper.AssertEqualsArray ("t.strings", exp.strings, t.strings);
224 AssertionHelper.AssertEqualsArray ("t.ushorts", exp.ushorts, t.ushorts);
226 TA.AssertEquals ("t.ta", exp.ta, t.ta);
228 AssertNotNull ("t.tam2", t.tam2);
229 CheckTaArray ("t.tam2", exp.tam2, t.tam2);
231 AssertNotNull ("t.tam3", t.tam3);
232 CheckTaArray ("t.tam3", exp.tam3, t.tam3);
234 AssertNotNull ("t.flatParts", t.flatParts);
235 CheckParts ("t.flatParts", exp.flatParts, t.flatParts);
237 // Null element is ignored
238 AssertNotNull ("t.flatParts2", t.flatParts2);
239 AssertEquals ("t.flatParts2.Length", 3, t.flatParts2.Length);
240 TA.AssertEquals ("t.flatParts2 0", exp.flatParts2[0], t.flatParts2[0]);
241 TA.AssertEquals ("t.flatParts2 1", exp.flatParts2[1], t.flatParts2[1]);
242 TA.AssertEquals ("t.flatParts2 2", exp.flatParts2[3], t.flatParts2[2]);
244 AssertNotNull ("t.anot", t.anot);
245 AssertEquals ("t.anot.lo", ((AnotherTestPart)exp.anot).lo, ((AnotherTestPart)t.anot).lo);
247 TestPart.AssertEquals ("t.ob", exp.ob as TestPart, t.ob as TestPart);
248 TestPart.AssertEquals ("t.ob2", exp.ob2 as TestPart, t.ob2 as TestPart);
250 AssertionHelper.AssertEqualsXml ("t.oneElem", exp.oneElem, t.oneElem);
251 AssertionHelper.AssertEqualsXml ("t.oneElem2", exp.oneElem2, t.oneElem2);
253 // One of the elements was null and it is ignored
254 AssertNotNull ("t.someElems", t.someElems);
255 AssertEquals ("t.someElems.Length", 2, t.someElems.Length);
256 AssertionHelper.AssertEqualsXml ("t.someElems[0]", exp.someElems[0], t.someElems[0]);
257 AssertionHelper.AssertEqualsXml ("t.someElems[1]", exp.someElems[2], t.someElems[1]);
259 AssertNotNull ("t.extraElems", t.extraElems);
260 AssertEquals ("t.extraElems.Length", exp.extraElems.Length, t.extraElems.Length);
261 for (int n=0; n<exp.extraElems.Length; n++)
262 AssertionHelper.AssertEqualsXml ("t.extraElems[" + n + "]", exp.extraElems[n], t.extraElems[n]);
264 AssertNotNull ("t.extraElems23", t.extraElems23);
265 AssertEquals ("t.extraElems23.Length", exp.extraElems23.Length, t.extraElems23.Length);
266 for (int n=0; n<t.extraElems23.Length; n++)
267 AssertionHelper.AssertEqualsXml ("t.extraElems23[" + n + "]", exp.extraElems23[n], t.extraElems23[n]);
269 AssertionHelper.AssertEqualsXml ("t.extraElemsRest", exp.extraElemsRest, t.extraElemsRest);
271 UnknownAttributeTester.AssertEquals ("t.uktester", exp.uktester, t.uktester);
273 AssertEquals ("t.ob3", exp.ob3, t.ob3);
274 AssertEquals ("t.ob4", exp.ob4, t.ob4);
275 AssertEquals ("t.op1", exp.op1, t.op1);
277 AssertionHelper.AssertEqualsArray ("t.opArray", exp.opArray, t.opArray);
279 AssertEquals ("t.ukOpt", exp.ukOpt, t.ukOpt);
280 AssertEquals ("t.opAtt", exp.opAtt, t.opAtt);
282 AssertionHelper.AssertEqualsArray ("t.byteArray", exp.byteArray, t.byteArray);
283 AssertionHelper.AssertEqualsArray ("t.byteByteArray", exp.byteByteArray, t.byteByteArray);
285 AssertNotNull ("t.ttList", t.ttList);
286 AssertionHelper.AssertEqualsArray ("t.ttList", exp.ttList.ToArray(), t.ttList.ToArray());
288 AssertNotNull ("t.RoList", t.RoList);
289 AssertEquals ("t.RoList.Count", exp.RoList.Count, t.RoList.Count);
290 for (int n=0; n<exp.RoList.Count; n++)
291 TestPart.AssertEquals ("t.RoList " + n, (TestPart)exp.RoList[n], (TestPart)t.RoList[n]);
293 AssertEquals ("t.struc.aa", exp.struc.aa, t.struc.aa);
294 AssertEquals ("t.struc.cc", exp.struc.cc, t.struc.cc);
296 AssertNotNull ("t.multiList", t.multiList);
297 AssertEquals ("t.multiList.Count", exp.multiList.Length, t.multiList.Length);
298 for (int n=0; n<exp.multiList.Length; n++)
299 AssertionHelper.AssertEqualsArray ("t.multiList " + n, exp.multiList[n].ToArray(), t.multiList[n].ToArray());
301 AssertEquals ("t.defElem", exp.defElem, t.defElem);
302 AssertEquals ("t.defAttr", exp.defAttr, t.defAttr);
304 CustomHashtable.AssertEquals ("t.special", exp.special, t.special);
306 AssertEquals ("t.attqname", exp.attqname, t.attqname);
308 AssertNotNull ("t.dbscontainer", t.dbscontainer);
309 DblStringContainer tdbca = t.dbscontainer.at as DblStringContainer;
310 DblStringContainer expdbca = exp.dbscontainer.at as DblStringContainer;
311 AssertNotNull ("t.dbscontainer.at", tdbca);
313 AssertNotNull ("t.dbscontainer.dbca", tdbca);
314 AssertionHelper.AssertEqualsArray ("t.dbscontainer.at.doublestring", expdbca.doublestring, tdbca.doublestring);
316 AnotherTestPart tat = tdbca.at as AnotherTestPart;
317 AnotherTestPart expat = expdbca.at as AnotherTestPart;
318 AssertNotNull ("t.dbscontainer.dbca.at", tat);
319 AssertEquals ("t.dbscontainer.dbca.at.lo", expat.lo, tat.lo);
322 void CheckParts (string id, TestPart[] exp, TestPart[] parts)
324 AssertionHelper.AssertType (id, exp, parts);
325 AssertEquals (id + " Len", exp.Length, parts.Length);
326 for (int n=0; n<exp.Length; n++)
327 TestPart.AssertEquals (id + "[" + n + "]", exp[n], parts[n]);
330 void CheckTaArray (string id, TA[][][] exp, TA[][][] arr)
332 AssertionHelper.AssertType (id, exp, arr);
333 AssertEquals (id + " Len", exp.Length, arr.Length);
334 for (int n=0; n<exp.Length; n++)
337 TA[][] expar = exp[n];
339 AssertionHelper.AssertType (id, expar, tar);
340 AssertEquals (expar.Length, tar.Length);
342 for (int m=0; m<expar.Length; m++)
345 TA[] expar2 = expar[m];
347 AssertionHelper.AssertType (id, expar2, tar2);
348 AssertEquals (id, expar2.Length, tar2.Length);
350 for (int i=0; i<expar2.Length; i++)
351 TA.AssertEquals (id + "[" + n + "][" + m + "][" + i + "]", expar2[i], tar2[i]);
357 public class AssertionHelper
359 public static bool AssertType (string id, object exp, object ob)
362 Assertion.AssertNull (id, ob);
366 Assertion.AssertNotNull (id, ob);
367 Assertion.AssertEquals (id + " type", exp.GetType(), ob.GetType());
372 public static void AssertEqualsXml (string id, XmlNode exp, XmlNode ob)
374 if (!AssertType (id, exp, ob)) return;
375 Assertion.AssertEquals (id, XmlSerializerTests.Infoset (exp), XmlSerializerTests.Infoset (ob));
378 public static void AssertEqualsArray (string id, Array exp, Array ob)
380 if (!AssertType (id, exp, ob)) return;
381 Assertion.AssertEquals (id + " Length", exp.GetLength(0), ob.GetLength(0));
382 for (int n=0; n<exp.GetLength(0); n++) {
383 object it = exp.GetValue(n);
385 AssertEqualsArray (id + "[" + n + "]", it as Array, ob.GetValue(n) as Array);
387 Assertion.AssertEquals (id + "[" + n + "]", it, ob.GetValue(n));
392 [XmlType(TypeName="")]
393 [XmlRoot(ElementName="aaaaaa",Namespace="")]
394 [XmlInclude(typeof(UknTestPart))]
395 [SoapInclude(typeof(UknTestPart))]
398 // public option op;elem.SchemaTypeName
401 [SoapElement(ElementName="suba")]
402 [XmlElement(ElementName="suba",Namespace="kk")]
409 [XmlAttribute (Namespace="attribns")]
412 [XmlElement(Namespace="oo")]
413 public TestPart part;
417 public TestPart[] parts;
419 [SoapElement(ElementName="multita")]
420 [XmlArray(ElementName="multita")]
421 // [XmlArrayItem(ElementName="itema",NestingLevel=1)]
422 [XmlArrayItem(ElementName="itema",Type=typeof(TA),NestingLevel=1)]
423 [XmlArrayItem(ElementName="itemb",Type=typeof(TB),NestingLevel=1)]
424 public TA[][] tam = new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}};
426 // [SoapElement(ElementName="multita2")]
428 [XmlArray(ElementName="multita2")]
429 [XmlArrayItem(ElementName="data1",NestingLevel=0)]
431 [XmlArrayItem(ElementName="data2",NestingLevel=1,Namespace="da2")]
432 [XmlArrayItem(ElementName="data3a",Type=typeof(TA),NestingLevel=2,Namespace="da3")]
433 [XmlArrayItem(ElementName="data3b",Type=typeof(TB),NestingLevel=2,Namespace="da3")]
434 public TA[][][] tam2;
437 public TA[][][] tam3;
439 [SoapElement(IsNullable=true)]
440 [XmlElement(IsNullable=true)]
441 public string mayBeNull;
443 public string[] strings;
445 [XmlArray(Namespace="arrayNamespace")]
446 public ushort[] ushorts;
449 public TestPart[] flatParts;
451 [SoapElement (ElementName="flatTAs")]
452 [XmlElement (ElementName="flatTAs")]
453 public TA[] flatParts2;
457 [XmlElement (Namespace="uimp")]
464 public XmlElement oneElem;
467 [XmlElement (ElementName="unElement", Namespace="elemns")]
468 public XmlElement oneElem2;
471 [XmlElement (ElementName="unsElements", Namespace="elemns")]
472 public XmlNode[] someElems;
475 [XmlAnyElement ("extra1")]
476 public XmlElement[] extraElems;
479 [XmlAnyElement ("extra2")]
480 [XmlAnyElement ("extra3")]
481 [XmlAnyElement ("extra3","nnn")]
482 public XmlElement[] extraElems23;
486 public XmlElement extraElemsRest;
488 public UnknownAttributeTester uktester;
491 public option[] opArray;
499 public byte[] byteArray;
501 public byte[][] byteByteArray;
503 [XmlElement(Type=typeof(string))]
504 [XmlElement(ElementName="kk",Type=typeof(int))]
505 public object[] tt = new object[] { "aa",22 };
507 public ArrayList ttList;
510 public ArrayList RoList
512 get { return roList; }
513 set { roList = value; }
518 public ArrayList[] multiList;
522 public OneStruct struc;
524 [DefaultValue("theDefValue")]
525 public string defElem;
528 [DefaultValue("theDefValue")]
529 public string defAttr;
531 [XmlText (Type=typeof(string))]
532 [XmlElement (Type=typeof(int))]
533 public object[] xmltext = new object[] {"aa",33,"bb",776};
536 public CustomHashtable special;
539 public XmlQualifiedName attqname;
542 public DateTime[] arrayAttribute;
544 [XmlArray (Namespace="mm")]
545 public string[][] dummyStringArray = new string[][] {null,null};
547 [XmlElement (Namespace="mm")]
548 public DblStringContainerAnm dbscontainer;
551 public class DblStringContainerAnm
556 [XmlType(Namespace="mm")]
557 public class DblStringContainer
559 [XmlArrayItem (NestingLevel=1, IsNullable=true)]
560 public string [][] doublestring;
564 [SoapType(TypeName="TC")]
565 [XmlType(TypeName="TC")]
566 [XmlInclude(typeof(TB))]
567 [SoapInclude(typeof(TB))]
574 public XmlNode[] extraTextNodes;
576 public static void AssertEquals (string id, TA expected, TA ob)
578 if (!AssertionHelper.AssertType (id, expected, ob)) return;
579 Assertion.AssertEquals (id + " xx", expected.xx, ob.xx);
580 // TODO: extraTextNodes
588 public static void AssertEquals (string id, TB expected, TB ob)
590 if (!AssertionHelper.AssertType (id, expected, ob)) return;
591 Assertion.AssertEquals (id + " yy", expected.yy, ob.yy);
592 TA.AssertEquals (id + " base", expected, ob);
596 public class UnknownAttributeTester
605 public XmlAttribute[] extraAtts;
607 // [XmlText(Type=typeof(XmlNode))]
608 // public XmlNode extraText;
610 public static void AssertEquals (string id, UnknownAttributeTester exp, UnknownAttributeTester ob)
612 if (!AssertionHelper.AssertType (id, exp, ob)) return;
613 Assertion.AssertEquals (id + " aa", exp.aa, ob.aa);
615 if (!AssertionHelper.AssertType (id + " extraAtts", exp.extraAtts, ob.extraAtts)) return;
618 for (int n=0; n<ob.extraAtts.Length; n++)
620 XmlAttribute at = ob.extraAtts [n];
621 if (at.NamespaceURI == "http://www.w3.org/2000/xmlns/") continue;
622 Assertion.Assert (id + " extraAtts length", p < exp.extraAtts.Length);
623 AssertionHelper.AssertEqualsXml (id + ".extraAtts " + n, exp.extraAtts [p], ob.extraAtts[n]);
629 [SoapType(TypeName="UnTestPart", Namespace="mm")]
630 [XmlType(TypeName="UnTestPart", Namespace="mm")]
631 public class TestPart
636 public static void AssertEquals (string id, TestPart expected, TestPart ob)
638 if (!AssertionHelper.AssertType (id, expected, ob)) return;
639 Assertion.AssertEquals (id + " name", expected.name, ob.name);
640 Assertion.AssertEquals (id + " bval", expected.bval, ob.bval);
644 [SoapType(Namespace="mm")]
645 [XmlType(Namespace="mm")]
646 public class AnotherTestPart
652 public class UknTestPart : Test
654 [XmlElement(IsNullable=true)]
659 public struct OneStruct
665 // [XmlType(Namespace="enum_namespace")]
669 [SoapEnum(Name="xmlBB")]
670 [XmlEnum(Name="xmlBB")]
676 public class CustomHashtable : IXmlSerializable
678 Hashtable data = new Hashtable ();
680 public void Add (string key, string value)
682 data.Add (key, value);
685 public static void AssertEquals (string id, CustomHashtable exp, CustomHashtable ob)
687 if (!AssertionHelper.AssertType (id, exp, ob)) return;
688 if (!AssertionHelper.AssertType (id, exp.data, ob.data)) return;
690 Assertion.AssertEquals (id + " data Count", exp.data.Count, ob.data.Count);
692 foreach (DictionaryEntry entry in exp.data)
693 Assertion.AssertEquals (entry.Value, ob.data[entry.Key]);
696 public void ReadXml (XmlReader reader)
698 // Read the element enclosing the object
699 reader.ReadStartElement();
700 reader.MoveToContent ();
702 // Reads the "data" element
703 reader.ReadStartElement();
704 reader.MoveToContent ();
705 while (reader.NodeType != XmlNodeType.EndElement)
707 if (reader.NodeType == XmlNodeType.Element)
709 string key = reader.LocalName;
710 data [key] = reader.ReadElementString ();
714 reader.MoveToContent ();
717 reader.ReadEndElement ();
720 public void WriteXml (XmlWriter writer)
722 writer.WriteStartElement ("data");
723 foreach (DictionaryEntry entry in data)
725 writer.WriteElementString ((string)entry.Key, (string)entry.Value);
727 writer.WriteEndElement ();
730 public XmlSchema GetSchema ()
732 XmlSchema s = new XmlSchema ();
733 s.TargetNamespace = "http://www.go-mono.org/schemas";
735 XmlSchemaElement e = new XmlSchemaElement ();
738 XmlSchemaComplexType cs = new XmlSchemaComplexType ();
739 XmlSchemaSequence seq = new XmlSchemaSequence ();
740 XmlSchemaAny any = new XmlSchemaAny ();
742 any.MaxOccurs = decimal.MaxValue;