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
25 [NUnit.Framework.Category("NotDotNet")] // FDBK50639
27 [Ignore ("JVM returns fields in different order")]
29 public void WriteLiteral ()
31 Test data = BuildTestObject ();
33 XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
34 XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
35 StringWriter sw = new StringWriter();
36 ss.Serialize (sw,data,nams);
37 string serialized = sw.ToString ();
38 serialized = XmlSerializerTests.Infoset (serialized);
40 StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
41 string expected = sr.ReadToEnd ();
44 expected = XmlSerializerTests.Infoset (expected);
45 Assert.AreEqual (expected, serialized);
49 [NUnit.Framework.Category ("NotDotNet")] // MS.NET results in compilation error (probably it generates bogus source.)
50 public void ReadLiteral ()
52 XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
53 XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
55 StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
56 Test data = (Test) ss.Deserialize (sr);
59 CheckObjectContent (BuildTestObject(), data);
62 XmlTypeMapping GetLiteralTypeMapping ()
64 XmlRootAttribute root = new XmlRootAttribute("rootroot");
65 Type[] types = new Type[] {typeof(UknTestPart), typeof(AnotherTestPart), typeof(DblStringContainer) };
66 XmlReflectionImporter ri = new XmlReflectionImporter ();
67 foreach (Type t in types) ri.IncludeType (t);
68 return ri.ImportTypeMapping (typeof(Test), root);
71 XmlTypeMapping GetEncodedTypeMapping ()
73 SoapReflectionImporter sri = new SoapReflectionImporter ();
74 sri.IncludeType (typeof(UknTestPart));
75 sri.IncludeType (typeof(AnotherTestPart));
76 sri.IncludeType (typeof(DblStringContainer));
77 return sri.ImportTypeMapping (typeof(Test));
80 Test BuildTestObject ()
82 XmlDocument doc = new XmlDocument();
84 Test t = new UknTestPart();
89 t.parts = new TestPart[3];
90 t.parts[0] = new TestPart();
91 t.parts[0].name = "un";
92 t.parts[0].bval = true;
93 t.parts[1] = new TestPart();
94 t.parts[1].name = "dos";
95 t.parts[1].bval = false;
96 t.parts[2] = t.parts[0];
98 t.strings = new string[] { "un", "dos", null, "tres" };
99 t.ushorts = new ushort[] { 1,2,3 };
101 t.ta.extraTextNodes = new XmlNode[] { doc.CreateTextNode ("AA"), doc.CreateTextNode ("BB") };
103 t.tam2 = new TA[][][]
105 new TA[][] { new TA[] {new TA(), new TA()}, new TA[] {new TA(), new TA()}},
106 new TA[][] { new TA[] {new TB(), new TA()}, new TA[] {new TB(), new TA()}},
107 new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}}
111 t.flatParts = t.parts;
113 t.flatParts2 = new TA[] {new TA(), new TB(), null, new TB()};
115 t.anot = new AnotherTestPart ();
116 ((AnotherTestPart)t.anot).lo = 1234567890;
121 XmlElement e1 = doc.CreateElement ("explicitElement");
122 XmlElement e2 = doc.CreateElement ("subElement");
123 e2.SetAttribute ("unAtrib","val");
124 doc.AppendChild (e1);
129 t.someElems = new XmlNode[3];
131 t.someElems[1] = null;
134 t.extraElems = new XmlElement[1];
135 t.extraElems[0] = doc.CreateElement ("extra1");
136 t.extraElems[0].SetAttribute ("val","1");
138 t.extraElems23 = new XmlElement[2];
139 t.extraElems23[0] = doc.CreateElement ("extra2");
140 t.extraElems23[0].SetAttribute ("val","2");
141 t.extraElems23[1] = doc.CreateElement ("extra3");
142 t.extraElems23[1].SetAttribute ("val","3");
144 t.extraElemsRest = doc.CreateElement ("extra4");
145 t.extraElemsRest.SetAttribute ("val","4");
147 t.uktester = new UnknownAttributeTester();
148 t.uktester.aa = "hihi";
150 t.uktester.extraAtts = new XmlAttribute[3];
151 t.uktester.extraAtts[0] = doc.CreateAttribute ("extraAtt1");
152 t.uktester.extraAtts[0].Value = "val1";
153 t.uktester.extraAtts[1] = doc.CreateAttribute ("extraAtt2");
154 t.uktester.extraAtts[1].Value = "val2";
155 t.uktester.extraAtts[2] = doc.CreateAttribute ("extraAtt3");
156 t.uktester.extraAtts[2].Value = "val3";
159 t.ob4 = (float)54321.12;
162 t.opArray = new option[] { option.CC, option.BB, option.AA };
166 t.byteArray = new byte[] { 11,33,55,222 };
167 t.byteByteArray = new byte[][] { t.byteArray, t.byteArray };
169 t.ttList = new ArrayList();
170 t.ttList.Add ("two");
171 t.ttList.Add ("strings");
172 // t.extraText = "Additional text";
174 t.RoList = new ArrayList ();
175 t.RoList.Add (t.parts[0]);
176 t.RoList.Add (t.parts[1]);
178 /* t.struc = new OneStruct();
180 t.struc.cc = "this is a struct";
182 t.multiList = new ArrayList[2];
183 t.multiList[0] = new ArrayList ();
184 t.multiList[0].Add (22);
185 t.multiList[0].Add (33);
186 t.multiList[1] = new ArrayList ();
187 t.multiList[1].Add (888);
188 t.multiList[1].Add (999);
190 // XmlSerializer does not deserialize default values explicitly.
191 //t.defElem = "theDefValue";
192 //t.defAttr = "theDefValue";
194 t.special = new CustomHashtable ();
195 t.special.Add ("one","1");
196 t.special.Add ("two","2");
197 t.special.Add ("three","3");
199 t.attqname = new XmlQualifiedName ("thename","thenamespace");
201 DblStringContainer dbc = new DblStringContainer ();
202 dbc.doublestring = new string [][] { null, new string[] {"hello"} };
203 AnotherTestPart at = new AnotherTestPart ();
207 DblStringContainerAnm dbca = new DblStringContainerAnm ();
209 t.dbscontainer = dbca;
214 void CheckObjectContent (Test exp, Test t)
216 Assert.AreEqual (exp.a, t.a, "t.a");
217 Assert.AreEqual (exp.b, t.b, "t.b");
218 Assert.AreEqual (exp.bbis, t.bbis, "t.bbis");
219 Assert.AreEqual (exp.c, t.c, "t.c");
221 Assert.IsNotNull (t.parts, "t.parts");
222 CheckParts ("t.parts", exp.parts, t.parts);
224 TestPart.AssertEquals ("t.part", exp.part, t.part);
226 AssertionHelper.AssertEqualsArray ("t.strings", exp.strings, t.strings);
227 AssertionHelper.AssertEqualsArray ("t.ushorts", exp.ushorts, t.ushorts);
229 TA.AssertEquals ("t.ta", exp.ta, t.ta);
231 Assert.IsNotNull (t.tam2, "t.tam2");
232 CheckTaArray ("t.tam2", exp.tam2, t.tam2);
234 Assert.IsNotNull (t.tam3, "t.tam3");
235 CheckTaArray ("t.tam3", exp.tam3, t.tam3);
237 Assert.IsNotNull (t.flatParts, "t.flatParts");
238 CheckParts ("t.flatParts", exp.flatParts, t.flatParts);
240 // Null element is ignored
241 Assert.IsNotNull (t.flatParts2, "t.flatParts2");
242 Assert.AreEqual (3, t.flatParts2.Length, "t.flatParts2.Length");
243 TA.AssertEquals ("t.flatParts2 0", exp.flatParts2[0], t.flatParts2[0]);
244 TA.AssertEquals ("t.flatParts2 1", exp.flatParts2[1], t.flatParts2[1]);
245 TA.AssertEquals ("t.flatParts2 2", exp.flatParts2[3], t.flatParts2[2]);
247 Assert.IsNotNull (t.anot, "t.anot");
248 Assert.AreEqual (((AnotherTestPart)exp.anot).lo, ((AnotherTestPart)t.anot).lo, "t.anot.lo");
250 TestPart.AssertEquals ("t.ob", exp.ob as TestPart, t.ob as TestPart);
251 TestPart.AssertEquals ("t.ob2", exp.ob2 as TestPart, t.ob2 as TestPart);
253 AssertionHelper.AssertEqualsXml ("t.oneElem", exp.oneElem, t.oneElem);
254 AssertionHelper.AssertEqualsXml ("t.oneElem2", exp.oneElem2, t.oneElem2);
256 // One of the elements was null and it is ignored
257 Assert.IsNotNull (t.someElems, "t.someElems");
258 Assert.AreEqual (2, t.someElems.Length, "t.someElems.Length");
259 AssertionHelper.AssertEqualsXml ("t.someElems[0]", exp.someElems[0], t.someElems[0]);
260 AssertionHelper.AssertEqualsXml ("t.someElems[1]", exp.someElems[2], t.someElems[1]);
262 Assert.IsNotNull (t.extraElems, "t.extraElems");
263 Assert.AreEqual (exp.extraElems.Length, t.extraElems.Length, "t.extraElems.Length");
264 for (int n=0; n<exp.extraElems.Length; n++)
265 AssertionHelper.AssertEqualsXml ("t.extraElems[" + n + "]", exp.extraElems[n], t.extraElems[n]);
267 Assert.IsNotNull (t.extraElems23, "t.extraElems23");
268 Assert.AreEqual (exp.extraElems23.Length, t.extraElems23.Length, "t.extraElems23.Length");
269 for (int n=0; n<t.extraElems23.Length; n++)
270 AssertionHelper.AssertEqualsXml ("t.extraElems23[" + n + "]", exp.extraElems23[n], t.extraElems23[n]);
272 AssertionHelper.AssertEqualsXml ("t.extraElemsRest", exp.extraElemsRest, t.extraElemsRest);
274 UnknownAttributeTester.AssertEquals ("t.uktester", exp.uktester, t.uktester);
276 Assert.AreEqual (exp.ob3, t.ob3, "t.ob3");
277 Assert.AreEqual (exp.ob4, t.ob4, "t.ob4");
278 Assert.AreEqual (exp.op1, t.op1, "t.op1");
280 AssertionHelper.AssertEqualsArray ("t.opArray", exp.opArray, t.opArray);
282 Assert.AreEqual (exp.ukOpt, t.ukOpt, "t.ukOpt");
283 Assert.AreEqual (exp.opAtt, t.opAtt, "t.opAtt");
285 AssertionHelper.AssertEqualsArray ("t.byteArray", exp.byteArray, t.byteArray);
286 AssertionHelper.AssertEqualsArray ("t.byteByteArray", exp.byteByteArray, t.byteByteArray);
288 Assert.IsNotNull (t.ttList, "t.ttList");
289 AssertionHelper.AssertEqualsArray ("t.ttList", exp.ttList.ToArray(), t.ttList.ToArray());
291 Assert.IsNotNull (t.RoList, "t.RoList");
292 Assert.AreEqual (exp.RoList.Count, t.RoList.Count, "t.RoList.Count");
293 for (int n=0; n<exp.RoList.Count; n++)
294 TestPart.AssertEquals ("t.RoList " + n, (TestPart)exp.RoList[n], (TestPart)t.RoList[n]);
296 Assert.AreEqual (exp.struc.aa, t.struc.aa, "t.struc.aa");
297 Assert.AreSame (exp.struc.cc, t.struc.cc, "t.struc.cc");
299 Assert.IsNotNull (t.multiList, "t.multiList");
300 Assert.AreEqual (exp.multiList.Length, t.multiList.Length, "t.multiList.Count");
301 for (int n=0; n<exp.multiList.Length; n++)
302 AssertionHelper.AssertEqualsArray ("t.multiList " + n, exp.multiList[n].ToArray(), t.multiList[n].ToArray());
304 Assert.AreEqual (exp.defElem, t.defElem, "t.defElem");
305 Assert.AreEqual (exp.defAttr, t.defAttr, "t.defAttr");
307 CustomHashtable.AssertEquals ("t.special", exp.special, t.special);
309 Assert.AreEqual (exp.attqname, t.attqname, "t.attqname");
311 Assert.IsNotNull (t.dbscontainer, "t.dbscontainer");
312 DblStringContainer tdbca = t.dbscontainer.at as DblStringContainer;
313 DblStringContainer expdbca = exp.dbscontainer.at as DblStringContainer;
314 Assert.IsNotNull (tdbca, "t.dbscontainer.at");
316 Assert.IsNotNull (tdbca, "t.dbscontainer.dbca");
317 AssertionHelper.AssertEqualsArray ("t.dbscontainer.at.doublestring", expdbca.doublestring, tdbca.doublestring);
319 AnotherTestPart tat = tdbca.at as AnotherTestPart;
320 AnotherTestPart expat = expdbca.at as AnotherTestPart;
321 Assert.IsNotNull (tat, "t.dbscontainer.dbca.at");
322 Assert.AreEqual (expat.lo, tat.lo, "t.dbscontainer.dbca.at.lo");
325 void CheckParts (string id, TestPart[] exp, TestPart[] parts)
327 AssertionHelper.AssertType (id, exp, parts);
328 Assert.AreEqual (exp.Length, parts.Length, id + " Len");
329 for (int n=0; n<exp.Length; n++)
330 TestPart.AssertEquals (id + "[" + n + "]", exp[n], parts[n]);
333 void CheckTaArray (string id, TA[][][] exp, TA[][][] arr)
335 AssertionHelper.AssertType (id, exp, arr);
336 Assert.AreEqual (exp.Length, arr.Length, id + " Len");
337 for (int n=0; n<exp.Length; n++)
340 TA[][] expar = exp[n];
342 AssertionHelper.AssertType (id, expar, tar);
343 Assert.AreEqual (expar.Length, tar.Length);
345 for (int m=0; m<expar.Length; m++)
348 TA[] expar2 = expar[m];
350 AssertionHelper.AssertType (id, expar2, tar2);
351 Assert.AreEqual (expar2.Length, tar2.Length, id);
353 for (int i=0; i<expar2.Length; i++)
354 TA.AssertEquals (id + "[" + n + "][" + m + "][" + i + "]", expar2[i], tar2[i]);
360 public class AssertionHelper
362 public static bool AssertType (string id, object exp, object ob)
365 Assert.IsNull (ob, id);
369 Assert.IsNotNull (ob, id);
370 Assert.AreEqual (exp.GetType(), ob.GetType(), id + " type");
375 public static void AssertEqualsXml (string id, XmlNode exp, XmlNode ob)
377 if (!AssertType (id, exp, ob)) return;
378 Assert.AreEqual (XmlSerializerTests.Infoset (exp), XmlSerializerTests.Infoset (ob), id);
381 public static void AssertEqualsArray (string id, Array exp, Array ob)
383 if (!AssertType (id, exp, ob)) return;
384 Assert.AreEqual (exp.GetLength(0), ob.GetLength(0), id + " Length");
385 for (int n=0; n<exp.GetLength(0); n++) {
386 object it = exp.GetValue(n);
388 AssertEqualsArray (id + "[" + n + "]", it as Array, ob.GetValue(n) as Array);
390 Assert.AreEqual (it, ob.GetValue(n), id + "[" + n + "]");
395 [XmlType(TypeName="")]
396 [XmlRoot(ElementName="aaaaaa",Namespace="")]
397 [XmlInclude(typeof(UknTestPart))]
398 [SoapInclude(typeof(UknTestPart))]
401 // public option op;elem.SchemaTypeName
404 [SoapElement(ElementName="suba")]
405 [XmlElement(ElementName="suba",Namespace="kk")]
412 [XmlAttribute (Namespace="attribns")]
415 [XmlElement(Namespace="oo")]
416 public TestPart part;
420 public TestPart[] parts;
422 [SoapElement(ElementName="multita")]
423 [XmlArray(ElementName="multita")]
424 // [XmlArrayItem(ElementName="itema",NestingLevel=1)]
425 [XmlArrayItem(ElementName="itema",Type=typeof(TA),NestingLevel=1)]
426 [XmlArrayItem(ElementName="itemb",Type=typeof(TB),NestingLevel=1)]
427 public TA[][] tam = new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}};
429 // [SoapElement(ElementName="multita2")]
431 [XmlArray(ElementName="multita2")]
432 [XmlArrayItem(ElementName="data1",NestingLevel=0)]
434 [XmlArrayItem(ElementName="data2",NestingLevel=1,Namespace="da2")]
435 [XmlArrayItem(ElementName="data3a",Type=typeof(TA),NestingLevel=2,Namespace="da3")]
436 [XmlArrayItem(ElementName="data3b",Type=typeof(TB),NestingLevel=2,Namespace="da3")]
437 public TA[][][] tam2;
440 public TA[][][] tam3;
442 [SoapElement(IsNullable=true)]
443 [XmlElement(IsNullable=true)]
444 public string mayBeNull;
446 public string[] strings;
448 [XmlArray(Namespace="arrayNamespace")]
449 public ushort[] ushorts;
452 public TestPart[] flatParts;
454 [SoapElement (ElementName="flatTAs")]
455 [XmlElement (ElementName="flatTAs")]
456 public TA[] flatParts2;
460 [XmlElement (Namespace="uimp")]
467 public XmlElement oneElem;
470 [XmlElement (ElementName="unElement", Namespace="elemns")]
471 public XmlElement oneElem2;
474 [XmlElement (ElementName="unsElements", Namespace="elemns")]
475 public XmlNode[] someElems;
478 [XmlAnyElement ("extra1")]
479 public XmlElement[] extraElems;
482 [XmlAnyElement ("extra2")]
483 [XmlAnyElement ("extra3")]
484 [XmlAnyElement ("extra3","nnn")]
485 public XmlElement[] extraElems23;
489 public XmlElement extraElemsRest;
491 public UnknownAttributeTester uktester;
494 public option[] opArray;
502 public byte[] byteArray;
504 public byte[][] byteByteArray;
506 [XmlElement(Type=typeof(string))]
507 [XmlElement(ElementName="kk",Type=typeof(int))]
508 public object[] tt = new object[] { "aa",22 };
510 public ArrayList ttList;
513 public ArrayList RoList
515 get { return roList; }
516 set { roList = value; }
521 public ArrayList[] multiList;
525 public OneStruct struc;
527 [DefaultValue("theDefValue")]
528 public string defElem;
531 [DefaultValue("theDefValue")]
532 public string defAttr;
534 [XmlText (Type=typeof(string))]
535 [XmlElement (Type=typeof(int))]
536 public object[] xmltext = new object[] {"aa",33,"bb",776};
539 public CustomHashtable special;
542 public XmlQualifiedName attqname;
545 public DateTime[] arrayAttribute;
547 [XmlArray (Namespace="mm")]
548 public string[][] dummyStringArray = new string[][] {null,null};
550 [XmlElement (Namespace="mm")]
551 public DblStringContainerAnm dbscontainer;
554 public class DblStringContainerAnm
559 [XmlType(Namespace="mm")]
560 public class DblStringContainer
562 [XmlArrayItem (NestingLevel=1, IsNullable=true)]
563 public string [][] doublestring;
567 [SoapType(TypeName="TC")]
568 [XmlType(TypeName="TC")]
569 [XmlInclude(typeof(TB))]
570 [SoapInclude(typeof(TB))]
577 public XmlNode[] extraTextNodes;
579 public static void AssertEquals (string id, TA expected, TA ob)
581 if (!AssertionHelper.AssertType (id, expected, ob)) return;
582 Assert.AreEqual (expected.xx, ob.xx, id + " xx");
583 // TODO: extraTextNodes
591 public static void AssertEquals (string id, TB expected, TB ob)
593 if (!AssertionHelper.AssertType (id, expected, ob)) return;
594 Assert.AreEqual (expected.yy, ob.yy, id + " yy");
595 TA.AssertEquals (id + " base", expected, ob);
599 public class UnknownAttributeTester
608 public XmlAttribute[] extraAtts;
610 // [XmlText(Type=typeof(XmlNode))]
611 // public XmlNode extraText;
613 public static void AssertEquals (string id, UnknownAttributeTester exp, UnknownAttributeTester ob)
615 if (!AssertionHelper.AssertType (id, exp, ob)) return;
616 Assert.AreEqual (exp.aa, ob.aa, id + " aa");
618 if (!AssertionHelper.AssertType (id + " extraAtts", exp.extraAtts, ob.extraAtts)) return;
621 for (int n=0; n<ob.extraAtts.Length; n++)
623 XmlAttribute at = ob.extraAtts [n];
624 if (at.NamespaceURI == "http://www.w3.org/2000/xmlns/") continue;
625 Assert.IsTrue (p < exp.extraAtts.Length, id + " extraAtts length");
626 AssertionHelper.AssertEqualsXml (id + ".extraAtts " + n, exp.extraAtts [p], ob.extraAtts[n]);
632 [SoapType(TypeName="UnTestPart", Namespace="mm")]
633 [XmlType(TypeName="UnTestPart", Namespace="mm")]
634 public class TestPart
639 public static void AssertEquals (string id, TestPart expected, TestPart ob)
641 if (!AssertionHelper.AssertType (id, expected, ob)) return;
642 Assert.AreEqual (expected.name, ob.name, id + " name");
643 Assert.AreEqual (expected.bval, ob.bval, id + " bval");
647 [SoapType(Namespace="mm")]
648 [XmlType(Namespace="mm")]
649 public class AnotherTestPart
655 public class UknTestPart : Test
657 [XmlElement(IsNullable=true)]
662 public struct OneStruct
668 // [XmlType(Namespace="enum_namespace")]
672 [SoapEnum(Name="xmlBB")]
673 [XmlEnum(Name="xmlBB")]
679 public class CustomHashtable : IXmlSerializable
681 Hashtable data = new Hashtable ();
683 public void Add (string key, string value)
685 data.Add (key, value);
688 public static void AssertEquals (string id, CustomHashtable exp, CustomHashtable ob)
690 if (!AssertionHelper.AssertType (id, exp, ob)) return;
691 if (!AssertionHelper.AssertType (id, exp.data, ob.data)) return;
693 Assert.AreEqual (exp.data.Count, ob.data.Count, id + " data Count");
695 foreach (DictionaryEntry entry in exp.data)
696 Assert.AreEqual (entry.Value, ob.data[entry.Key]);
699 public void ReadXml (XmlReader reader)
701 // Read the element enclosing the object
702 reader.ReadStartElement();
703 reader.MoveToContent ();
705 // Reads the "data" element
706 reader.ReadStartElement();
707 reader.MoveToContent ();
708 while (reader.NodeType != XmlNodeType.EndElement)
710 if (reader.NodeType == XmlNodeType.Element)
712 string key = reader.LocalName;
713 data [key] = reader.ReadElementString ();
717 reader.MoveToContent ();
720 reader.ReadEndElement ();
723 public void WriteXml (XmlWriter writer)
725 writer.WriteStartElement ("data");
726 foreach (DictionaryEntry entry in data)
728 writer.WriteElementString ((string)entry.Key, (string)entry.Value);
730 writer.WriteEndElement ();
733 public XmlSchema GetSchema ()
735 XmlSchema s = new XmlSchema ();
736 s.TargetNamespace = "http://www.go-mono.org/schemas";
738 XmlSchemaElement e = new XmlSchemaElement ();
741 XmlSchemaComplexType cs = new XmlSchemaComplexType ();
742 XmlSchemaSequence seq = new XmlSchemaSequence ();
743 XmlSchemaAny any = new XmlSchemaAny ();
745 any.MaxOccurs = decimal.MaxValue;