2 // DataSetInferXmlSchemaTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
10 using System.Collections;
14 using NUnit.Framework;
16 namespace MonoTests.System.Data
19 public class DataSetInferXmlSchemaTest : DataSetAssertion
21 string xml1 = "<root/>";
22 string xml2 = "<root attr='value' />";
23 string xml3 = "<root attr='value' attr2='2' />";
24 string xml4 = "<root>simple.txt</root>";
25 string xml5 = "<root><child/></root>";
26 string xml6 = "<root><col1>sample</col1></root>";
27 string xml7 = @"<root>
\r
28 <col1>column 1 test</col1>
\r
29 <col2>column2test</col2>
\r
32 string xml8 = @"<set>
\r
39 string xml9 = @"<el1 attr1='val1' attrA='valA'>
\r
40 <el2 attr2='val2' attrB='valB'>
\r
41 <el3 attr3='val3' attrC='valC'>3</el3>
\r
42 <column2>1</column2>
\r
43 <column3>1</column3>
\r
44 <el4 attr4='val4' attrD='valD'>4</el4>
\r
47 string xml10 = "<root>Here is a <b>mixed</b> content.</root>";
48 string xml11 = @"<root xml:space='preserve'>
\r
49 <child_after_significant_space />
\r
51 // This is useless ... since xml:space becomes a DataColumn here.
52 // string xml12 = "<root xml:space='preserve'> </root>";
53 // The result is silly under MS.NET. It never ignores comment, so
55 // 1) <root>simple string.</root>
56 // 2) <root>simple <!-- comment -->string.</root>
57 // The same applies to PI.
58 // string xml13 = "<root><tab><col>test <!-- out --> comment</col></tab></root>";
59 string xml14 = "<p:root xmlns:p='urn:foo'>test string</p:root>";
60 string xml15 = @"<root>
\r
62 <col1_1>test1</col1_1>
\r
63 <col1_2>test2</col1_2>
\r
66 <col2_1>test1</col2_1>
\r
67 <col2_2>test2</col2_2>
\r
70 string xml16 = @"<root>
\r
73 <tableFooChild1>1</tableFooChild1>
\r
74 <tableFooChild2>2</tableFooChild2>
\r
81 string xml17 = @"<root xmlns='urn:foo' />";
82 string xml18 = @"<set>
\r
87 <col>simple text here.</col>
\r
90 string xml19 =@"<set>
\r
92 <col>simple text</col><!-- ignored -->
\r
98 string xml20 = @"<set>
\r
103 <col attr='value' />
\r
106 string xml21 = @"<set>
\r
114 private DataSet GetDataSet (string xml, string [] nss)
116 DataSet ds = new DataSet ();
117 ds.InferXmlSchema (new XmlTextReader (xml, XmlNodeType.Document, null), nss);
122 public void NullFileName ()
124 DataSet ds = new DataSet ();
125 ds.InferXmlSchema ((XmlReader) null, null);
126 AssertDataSet ("null", ds, "NewDataSet", 0);
130 public void SingleElement ()
132 DataSet ds = GetDataSet (xml1, null);
133 AssertDataSet ("xml1", ds, "root", 0, 0);
135 ds = GetDataSet (xml4, null);
136 AssertDataSet ("xml4", ds, "root", 0, 0);
139 ds = GetDataSet (xml14, null);
140 AssertDataSet ("xml14", ds, "root", 0, 0);
141 AssertEquals ("p", ds.Prefix);
142 AssertEquals ("urn:foo", ds.Namespace);
144 ds = GetDataSet (xml17, null);
145 AssertDataSet ("xml17", ds, "root", 0, 0);
146 AssertEquals ("urn:foo", ds.Namespace);
150 public void SingleElementWithAttribute ()
152 DataSet ds = GetDataSet (xml2, null);
153 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
154 DataTable dt = ds.Tables [0];
155 AssertDataTable ("dt", dt, "root", 1, 0);
156 AssertDataColumn ("col", dt.Columns [0], "attr", true, false, 0, 1, "attr", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
160 public void SingleElementWithTwoAttribute ()
162 DataSet ds = GetDataSet (xml3, null);
163 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
164 DataTable dt = ds.Tables [0];
165 AssertDataTable ("dt", dt, "root", 2, 0);
166 AssertDataColumn ("col", dt.Columns [0], "attr", true, false, 0, 1, "attr", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
167 AssertDataColumn ("col", dt.Columns [1], "attr2", true, false, 0, 1, "attr2", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
171 public void SingleChild ()
173 DataSet ds = GetDataSet (xml5, null);
174 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
175 DataTable dt = ds.Tables [0];
176 AssertDataTable ("dt", dt, "root", 1, 0);
177 AssertDataColumn ("col", dt.Columns [0], "child", true, false, 0, 1, "child", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
179 ds = GetDataSet (xml6, null);
180 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
182 AssertDataTable ("dt", dt, "root", 1, 0);
183 AssertDataColumn ("col", dt.Columns [0], "col1", true, false, 0, 1, "col1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
187 public void SimpleElementTable ()
189 DataSet ds = GetDataSet (xml7, null);
190 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
191 DataTable dt = ds.Tables [0];
192 AssertDataTable ("dt", dt, "root", 3, 0);
193 AssertDataColumn ("col", dt.Columns [0], "col1", true, false, 0, 1, "col1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
194 AssertDataColumn ("col2", dt.Columns [1], "col2", true, false, 0, 1, "col2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
195 AssertDataColumn ("col3", dt.Columns [2], "col3", true, false, 0, 1, "col3", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
199 public void SimpleDataSet ()
201 DataSet ds = GetDataSet (xml8, null);
202 AssertDataSet ("ds", ds, "set", 1, 0);
203 DataTable dt = ds.Tables [0];
204 AssertDataTable ("dt", dt, "tab", 3, 0);
205 AssertDataColumn ("col", dt.Columns [0], "col1", true, false, 0, 1, "col1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
206 AssertDataColumn ("col2", dt.Columns [1], "col2", true, false, 0, 1, "col2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
207 AssertDataColumn ("col3", dt.Columns [2], "col3", true, false, 0, 1, "col3", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
211 public void ComplexElementAttributeTable1 ()
213 // FIXME: Also test ReadXml (, XmlReadMode.InferSchema) and
214 // make sure that ReadXml() stores DataRow to el1 (and maybe to others)
215 DataSet ds = GetDataSet (xml9, null);
216 AssertDataSet ("ds", ds, "NewDataSet", 4, 0);
217 DataTable dt = ds.Tables [0];
219 AssertDataTable ("dt", dt, "el1", 3, 0);
220 AssertDataColumn ("el1_Id", dt.Columns [0], "el1_Id", false, true, 0, 1, "el1_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
221 AssertDataColumn ("el1_attr1", dt.Columns [1], "attr1", true, false, 0, 1, "attr1", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
222 AssertDataColumn ("el1_attrA", dt.Columns [2], "attrA", true, false, 0, 1, "attrA", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
225 AssertDataTable ("dt", dt, "el2", 6, 0);
226 AssertDataColumn ("el2_Id", dt.Columns [0], "el2_Id", false, true, 0, 1, "el2_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
227 AssertDataColumn ("el2_col2", dt.Columns [1], "column2", true, false, 0, 1, "column2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
228 AssertDataColumn ("el2_col3", dt.Columns [2], "column3", true, false, 0, 1, "column3", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
229 AssertDataColumn ("el2_attr2", dt.Columns [3], "attr2", true, false, 0, 1, "attr2", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 3, String.Empty, false, false);
230 AssertDataColumn ("el2_attrB", dt.Columns [4], "attrB", true, false, 0, 1, "attrB", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 4, String.Empty, false, false);
231 AssertDataColumn ("el2_el1Id", dt.Columns [5], "el1_Id", true, false, 0, 1, "el1_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 5, String.Empty, false, false);
234 AssertDataTable ("dt", dt, "el3", 4, 0);
235 AssertDataColumn ("el3_attr3", dt.Columns [0], "attr3", true, false, 0, 1, "attr3", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
236 AssertDataColumn ("el3_attrC", dt.Columns [1], "attrC", true, false, 0, 1, "attrC", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
237 AssertDataColumn ("el3_Text", dt.Columns [2], "el3_Text", true, false, 0, 1, "el3_Text", MappingType.SimpleContent, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
238 AssertDataColumn ("el3_el2Id", dt.Columns [3], "el2_Id", true, false, 0, 1, "el2_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 3, String.Empty, false, false);
241 AssertDataTable ("dt", dt, "el4", 4, 0);
242 AssertDataColumn ("el3_attr4", dt.Columns [0], "attr4", true, false, 0, 1, "attr4", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
243 AssertDataColumn ("el4_attrD", dt.Columns [1], "attrD", true, false, 0, 1, "attrD", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
244 AssertDataColumn ("el4_Text", dt.Columns [2], "el4_Text", true, false, 0, 1, "el4_Text", MappingType.SimpleContent, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
245 AssertDataColumn ("el4_el2Id", dt.Columns [4], "el2_Id", true, false, 0, 1, "el2_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 3, String.Empty, false, false);
249 public void MixedContent ()
251 // Note that text part is ignored.
253 DataSet ds = GetDataSet (xml10, null);
254 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
255 DataTable dt = ds.Tables [0];
256 AssertDataTable ("dt", dt, "root", 1, 0);
257 AssertDataColumn ("col", dt.Columns [0], "b", true, false, 0, 1, "b", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
261 public void SignificantWhitespaceIgnored ()
263 // Note that 1) significant whitespace is ignored, and
264 // 2) xml:space is treated as column (and also note namespaces).
265 DataSet ds = GetDataSet (xml11, null);
266 AssertDataSet ("ds", ds, "NewDataSet", 1, 0);
267 DataTable dt = ds.Tables [0];
268 AssertDataTable ("dt", dt, "root", 2, 0);
269 AssertDataColumn ("element", dt.Columns [0], "child_after_significant_space", true, false, 0, 1, "child_after_significant_space", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
270 AssertDataColumn ("xml:space", dt.Columns [1], "space", true, false, 0, 1, "space", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, "http://www.w3.org/XML/1998/namespace", 1, "xml", false, false);
274 public void SignificantWhitespaceIgnored2 ()
276 // To make sure, create pure significant whitespace element
277 // using XmlNodeReader (that does not have xml:space attribute
279 DataSet ds = new DataSet ();
\r
280 XmlDocument doc = new XmlDocument ();
\r
281 doc.AppendChild (doc.CreateElement ("root"));
\r
282 doc.DocumentElement.AppendChild (doc.CreateSignificantWhitespace
\r
284 XmlReader xr = new XmlNodeReader (doc);
\r
285 ds.InferXmlSchema (xr, null);
\r
286 AssertDataSet ("pure_whitespace", ds, "root", 0);
\r
290 public void TwoElementTable ()
292 // FIXME: Also test ReadXml (, XmlReadMode.InferSchema) and
293 // make sure that ReadXml() stores DataRow to el1 (and maybe to others)
294 DataSet ds = GetDataSet (xml15, null);
295 AssertDataSet ("ds", ds, "root", 2, 0);
297 DataTable dt = ds.Tables [0];
298 AssertDataTable ("dt", dt, "table1", 2, 0);
299 AssertDataColumn ("col1_1", dt.Columns [0], "col1_1", true, false, 0, 1, "col1_1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
300 AssertDataColumn ("col1_2", dt.Columns [1], "col1_2", true, false, 0, 1, "col1_2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
303 AssertDataTable ("dt", dt, "table2", 2, 0);
304 AssertDataColumn ("col2_1", dt.Columns [0], "col2_1", true, false, 0, 1, "col2_1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
305 AssertDataColumn ("col2_2", dt.Columns [1], "col2_2", true, false, 0, 1, "col2_2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
309 [ExpectedException (typeof (ArgumentException))]
310 // The same table cannot be the child table in two nested relations.
311 public void ComplexElementTable1 ()
313 // TODO: Also test ReadXml (, XmlReadMode.InferSchema) and
314 // make sure that ReadXml() stores DataRow to el1 (and maybe to others)
315 DataSet ds = GetDataSet (xml16, null);
317 AssertDataSet ("ds", ds, "NewDataSet", 4, 0);
319 DataTable dt = ds.Tables [0];
320 AssertDataTable ("dt", dt, "root", 2, 0);
321 AssertDataColumn ("table#1_id", dt.Columns [0], "root_Id", false, true, 0, 1, "root_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
322 AssertDataColumn ("table#1_bar", dt.Columns [1], "bar", true, false, 0, 1, "bar", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
325 AssertDataTable ("dt2", dt, "table", 3, 0);
326 AssertDataColumn ("table#2_id", dt.Columns [0], "table_Id", false, true, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
327 AssertDataColumn ("table#2_bar", dt.Columns [1], "bar", true, false, 0, 1, "bar", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
328 AssertDataColumn ("table#2_refid", dt.Columns [0], "root_Id", true, false, 0, 1, "root_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
331 AssertDataTable ("dt3", dt, "foo", 3, 0);
332 AssertDataColumn ("table#3_col1", dt.Columns [0], "tableFooChild1", true, false, 0, 1, "tableFooChild1", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
333 AssertDataColumn ("table#3_col2", dt.Columns [0], "tableFooChild2", true, false, 0, 1, "tableFooChild2", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
334 AssertDataColumn ("table#3_refid", dt.Columns [0], "table_Id", true, false, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
339 public void TwoElementTable3 ()
341 DataSet ds = GetDataSet (xml18, null);
342 AssertDataSet ("ds", ds, "set", 2, 1);
344 DataTable dt = ds.Tables [0];
345 AssertDataTable ("dt", dt, "table", 1, 0);
346 AssertDataColumn ("table_Id", dt.Columns [0], "table_Id", false, true, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
349 AssertDataTable ("dt", dt, "col", 2, 0);
350 AssertDataColumn ("another_col", dt.Columns [0], "another_col", true, false, 0, 1, "another_col", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
351 AssertDataColumn ("table_refId", dt.Columns [1], "table_Id", true, false, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
353 DataRelation dr = ds.Relations [0];
354 AssertDataRelation ("rel", dr, "table_col", new string [] {"table_Id"}, new string [] {"table_Id"}, true, true);
355 AssertUniqueConstraint ("uniq", dr.ParentKeyConstraint, "Constraint1", true, new string [] {"table_Id"});
356 AssertForeignKeyConstraint ("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string [] {"table_Id"}, new string [] {"table_Id"});
360 public void ConflictColumnTable ()
362 DataSet ds = GetDataSet (xml19, null);
363 AssertDataSet ("ds", ds, "set", 2, 1);
365 DataTable dt = ds.Tables [0];
366 AssertDataTable ("dt", dt, "table", 1, 0);
367 AssertDataColumn ("table_Id", dt.Columns [0], "table_Id", false, true, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
370 AssertDataTable ("dt", dt, "col", 2, 0);
371 AssertDataColumn ("table_refId", dt.Columns [1], "table_Id", true, false, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
372 AssertDataColumn ("another_col", dt.Columns [0], "another_col", true, false, 0, 1, "another_col", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
374 DataRelation dr = ds.Relations [0];
375 AssertDataRelation ("rel", dr, "table_col", new string [] {"table_Id"}, new string [] {"table_Id"}, true, true);
376 AssertUniqueConstraint ("uniq", dr.ParentKeyConstraint, "Constraint1", true, new string [] {"table_Id"});
377 AssertForeignKeyConstraint ("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string [] {"table_Id"}, new string [] {"table_Id"});
381 public void ConflictColumnTableAttribute ()
383 // Conflicts between a column and a table, additionally an attribute.
384 DataSet ds = GetDataSet (xml20, null);
385 AssertDataSet ("ds", ds, "set", 2, 1);
387 DataTable dt = ds.Tables [0];
388 AssertDataTable ("dt", dt, "table", 1, 0);
389 AssertDataColumn ("table_Id", dt.Columns [0], "table_Id", false, true, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, true);
392 AssertDataTable ("dt", dt, "col", 3, 0);
393 AssertDataColumn ("another_col", dt.Columns [0], "another_col", true, false, 0, 1, "another_col", MappingType.Element, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 0, String.Empty, false, false);
394 AssertDataColumn ("table_refId", dt.Columns [1], "table_Id", true, false, 0, 1, "table_Id", MappingType.Hidden, typeof (int), DBNull.Value, String.Empty, -1, String.Empty, 1, String.Empty, false, false);
395 AssertDataColumn ("attr", dt.Columns [2], "attr", true, false, 0, 1, "attr", MappingType.Attribute, typeof (string), DBNull.Value, String.Empty, -1, String.Empty, 2, String.Empty, false, false);
397 DataRelation dr = ds.Relations [0];
398 AssertDataRelation ("rel", dr, "table_col", new string [] {"table_Id"}, new string [] {"table_Id"}, true, true);
399 AssertUniqueConstraint ("uniq", dr.ParentKeyConstraint, "Constraint1", true, new string [] {"table_Id"});
400 AssertForeignKeyConstraint ("fkey", dr.ChildKeyConstraint, "table_col", AcceptRejectRule.None, Rule.Cascade, Rule.Cascade, new string [] {"table_Id"}, new string [] {"table_Id"});
404 [ExpectedException (typeof (DataException))]
405 public void ConflictAttributeDataTable ()
407 // attribute "data" becomes DataTable, and when column "data"
408 // appears, it cannot be DataColumn, since the name is
409 // already allocated for DataTable.
410 DataSet ds = GetDataSet (xml21, null);