2004-03-31 Juraj Skripsky <juraj@hotfeet.ch>
[mono.git] / mcs / class / System.Data / System.Data / XmlSchemaMapper.cs
1 //
2 // mcs/class/System.Data/System.Data/XmlSchemaMapper.cs
3 //
4 // Purpose: Maps XmlSchema to DataSet 
5 //
6 // class: XmlSchemaMapper
7 // assembly: System.Data.dll
8 // namespace: System.Data
9 //
10 // Author:
11 //     Ville Palo <vi64pa@koti.soon.fi>
12 //
13 // (C) 2002 Ville Palo
14 //
15 //
16
17 using System;
18 using System.Data;
19 using System.Xml;
20 using System.Xml.Schema;
21 using System.Collections;
22 using System.Globalization;
23
24 namespace System.Data {
25
26         internal class XmlSchemaMapper
27         {       
28                 #region Fields
29
30                 private DataSet DSet;
31                 private DataTable table;
32                 enum ElementType {ELEMENT_UNDEFINED, ELEMENT_TABLE, ELEMENT_COLUMN};
33                 private Hashtable TypeCollection = new Hashtable ();
34                 private Hashtable ElementCollection = new Hashtable ();
35
36                 #endregion // Fields
37
38                 #region Constructors
39
40                 public XmlSchemaMapper (DataSet dataset)
41                 {
42                         DSet = dataset;
43                 }
44
45                 public XmlSchemaMapper (DataTable datatable)
46                 {
47                         table = datatable;
48                 }
49                 
50                 #endregion // Constructors
51
52                 #region Public methods
53
54                 public void Read (XmlReader Reader)
55                 {
56                         XmlSchema Schema = XmlSchema.Read (Reader, new ValidationEventHandler (OnXmlSchemaValidation));
57                         if (DSet != null) DSet.Namespace = Schema.TargetNamespace;
58
59                         // read items
60                         foreach (XmlSchemaObject Item in Schema.Items)
61                                 ReadXmlSchemaItem (Item);
62                 }
63
64                 #endregion // Public methods
65
66                 #region Private methods
67
68                 private void ReadXmlSchemaItem (XmlSchemaObject Item)
69                 {
70                         XmlSchemaObject SchemaObject;
71                         
72                         if (Item is XmlSchemaType)
73                                 ReadXmlSchemaType ((XmlSchemaType)Item);
74                         else if (Item is XmlSchemaElement)
75                                 ReadXmlSchemaElement (Item as XmlSchemaElement, ElementType.ELEMENT_UNDEFINED);
76                 }
77
78                 private void ReadXmlSchemaSequence (XmlSchemaSequence Sequence)
79                 {
80                         ReadXmlSchemaSequence (Sequence, null);
81                 }
82
83                 private void ReadXmlSchemaSequence (XmlSchemaSequence Sequence, DataTable Table)
84                 {
85                         foreach (XmlSchemaObject TempObj in Sequence.Items) {
86                                 if (TempObj is XmlSchemaElement){
87                                         XmlSchemaElement schemaElement = (XmlSchemaElement)TempObj;
88                                         // the element can be a Column or a Table
89                                         // tables do not have a type.
90                                         if (schemaElement.SchemaTypeName.Name.Length > 0 || (schemaElement.SchemaType is XmlSchemaSimpleType))
91                                                 ReadXmlSchemaElement (schemaElement, ElementType.ELEMENT_COLUMN, Table);
92                                         else
93                                                 ReadXmlSchemaElement (schemaElement, ElementType.ELEMENT_TABLE, Table);
94                                 }
95                         }
96                 }
97
98                 private void ReadXmlSchemaChoice (XmlSchemaChoice Choice)
99                 {
100                         XmlSchemaObject SchemaObject;
101                         foreach (XmlSchemaObject TempObject in Choice.Items) {
102                                 if ((SchemaObject = TempObject as XmlSchemaElement) != null)
103                                         ReadXmlSchemaElement ((XmlSchemaElement)SchemaObject, ElementType.ELEMENT_TABLE);
104                         }
105                 }
106
107                 private void ReadXmlSchemaElement (XmlSchemaElement Element)
108                 {
109                         ReadXmlSchemaElement (Element, ElementType.ELEMENT_UNDEFINED);
110                 }
111
112                 private void ReadXmlSchemaElement (XmlSchemaElement Element, ElementType ElType)
113                 {
114                         ReadXmlSchemaElement (Element, ElType, null);
115                 }
116
117                 private void ReadXmlSchemaElement (XmlSchemaElement Element, ElementType ElType, DataTable Table)
118                 {
119                         Hashtable Attributes = ReadUnhandledAttributes (Element.UnhandledAttributes);
120                         DataTable Table2 = null;
121
122                         if (Attributes.Contains (XmlConstants.IsDataSet)) { // DataSet -elemt
123                         
124                                 if (String.Compare (Attributes [XmlConstants.IsDataSet].ToString (), "true", true) == 0 && DSet != null)
125                                         DSet.DataSetName = Element.Name;
126
127                                 if (Attributes.Contains (XmlConstants.Locale)) {
128                                         CultureInfo cinfo = new CultureInfo((String)Attributes [XmlConstants.Locale]);
129                                         if (DSet != null) DSet.Locale = cinfo;
130                                         else table.Locale = cinfo;
131                                 }
132                         }
133                         else if (Element.SchemaTypeName != null && Element.SchemaTypeName.Namespace != XmlConstants.SchemaNamespace 
134                                  && Element.SchemaTypeName.Name != String.Empty) {
135
136                                 //
137                                 // If type is not standard type
138                                 //
139
140                                 if (DSet == null) throw new InvalidOperationException ("Schema not valid for a DataTable");
141                                 
142                                 DataTable TempTable = new DataTable (Element.Name);
143                                 DSet.Tables.Add (TempTable);
144                                 
145                                 // If type is already defined in schema read it...                              
146                                 if (TypeCollection.Contains (Element.SchemaTypeName.ToString ()))
147                                         ReadXmlSchemaType ((XmlSchemaType)TypeCollection [Element.SchemaTypeName.ToString ()], TempTable);
148                                 else // but if it's not yet defined put it safe to wait if we need it later. 
149                                         ElementCollection.Add (Element.SchemaTypeName.Name, TempTable);
150
151                         }
152                         else if (Element.RefName != null && Element.RefName.Name != string.Empty) { // if there is a ref=
153
154                                 if (ElementCollection.Contains (Element.RefName.Name))
155                                         ReadXmlSchemaElement ((XmlSchemaElement)ElementCollection [Element.RefName.Name], ElementType.ELEMENT_TABLE);
156                         }
157                         else if (ElementType.ELEMENT_UNDEFINED != ElType) {
158                                 
159                                 if (ElType == ElementType.ELEMENT_TABLE){
160                                         ReadTable (Element);
161                                         // we have to return else all child element of the table will be computed again.
162                                         return;
163                                 }
164                                 else if (ElType == ElementType.ELEMENT_COLUMN && Table != null)
165                                         ReadColumn (Element, Table);
166                         }
167                         else {
168                                 // this element is undefined, for now
169                                 ElementCollection.Add (Element.Name, Element);
170                         }
171
172                         // Read Element type
173                         if (Element.SchemaType != null)
174                                 ReadXmlSchemaType (Element.SchemaType);
175
176                         // Read possible constraints
177                         if (Element.Constraints != null && Element.Constraints.Count > 0){
178                                 ReadXmlSchemaConstraints (Element.Constraints);
179                         }
180                 }
181
182                 private void ReadTable (XmlSchemaElement Element)
183                 {
184                         DataTable TempTable = null;
185                         
186                         // Add the table to the DataSet only if it is not already in there.
187                         if (DSet != null) {
188                                 if (DSet.Tables.Contains (Element.Name)) return;
189                                 TempTable = new DataTable (Element.Name);
190                                 DSet.Tables.Add (TempTable);
191                         }
192                         else {
193                                 if (table.TableName.Length != 0) 
194                                         throw new InvalidOperationException ("More than one table is defined in this schema");
195                                 table.TableName = Element.Name;
196                                 TempTable = table;
197                         }
198                         ReadXmlSchemaType (Element.SchemaType, TempTable);
199                 }
200
201                 private void ReadColumn (XmlSchemaElement Element, DataTable Table)
202                 {
203                         DataColumn Column = new DataColumn (Element.Name);
204                         Column.DataType = GetColumnType(Element.SchemaTypeName.Name);
205                         Table.Columns.Add (Column);
206
207                         if (Element.UnhandledAttributes != null) {
208                                 
209                                 foreach (XmlAttribute Attr in Element.UnhandledAttributes) {
210                                         switch (Attr.LocalName) {
211                                                 
212                                         case XmlConstants.Caption:
213                                                 Column.Caption = Attr.Value;
214                                                 break;
215                                         case XmlConstants.DataType:
216                                                 Column.DataType = Type.GetType (Attr.Value);
217                                                 break;
218                                         case XmlConstants.AutoIncrement:
219                                                 Column.AutoIncrement = bool.Parse(Attr.Value);
220                                                 break;
221                                         case XmlConstants.AutoIncrementSeed:
222                                                 Column.AutoIncrementSeed = int.Parse(Attr.Value);
223                                                 break;
224                                         default:
225                                                 break;
226                                         }
227                                 }
228                         }
229
230                         //
231                         // Handel rest of the parameters
232                         //
233
234                         if (Column.DataType == null)
235                                 Column.DataType = Type.GetType ("System.String");
236                         
237                         if (Element.DefaultValue != null)
238                                 Column.DefaultValue = Element.DefaultValue;
239
240                         // If Element have type
241                         if (Element.SchemaType != null)
242                                 ReadXmlSchemaType (Element.SchemaType, Column);
243
244                 }
245
246                 private Type GetColumnType (String typeName)
247                 {
248                         if (typeName == null || typeName.Length == 0)
249                                 return typeof (string);
250                         Type t;
251                         switch (typeName) {
252                         case "char":
253                                 t = typeof (char);
254                                 break;
255                         case "int" :
256                                 t = typeof (int);
257                                 break;
258                         case "unsignedInt" :
259                                 t = typeof (uint);
260                                 break;
261                         case "unsignedByte" :
262                                 t = typeof (byte);
263                                 break;
264                         case "byte" :
265                                 t = typeof (sbyte);
266                                 break;
267                         case "short" :
268                                 t = typeof (short);
269                                 break;
270                         case "usignedShort" :
271                                 t = typeof (ushort);
272                                 break;
273                         case "long" :
274                                 t = typeof (long);
275                                 break;
276                         case "unsignedLong" :
277                                 t = typeof (ulong);
278                                 break;
279                         case "boolean" :
280                                 t = typeof (bool);
281                                 break;
282                         case "float" :
283                                 t = typeof (float);
284                                 break;
285                         case "double" :
286                                 t = typeof (double);
287                                 break;
288                         case "decimal" :
289                                 t = typeof (decimal);
290                                 break;
291                         case "dateTime" :
292                                 t = typeof (DateTime);
293                                 break;
294                         case "duration" :
295                                 t = typeof (TimeSpan);
296                                 break;
297                         case "base64Binary" :
298                                 t = typeof (byte[]);
299                                 break;
300                         default :
301                                 t = typeof (string);
302                                 break;
303                         }
304                         
305                         return t;
306                 }
307
308                 // Makes new Hashtable of the attributes.
309                 private Hashtable ReadUnhandledAttributes (XmlAttribute [] Attributes)
310                 {
311                         Hashtable Result = new Hashtable ();
312
313                         if (Attributes == null)
314                                 return Result;
315
316                         foreach (XmlAttribute attribute in Attributes) {
317                                 Result.Add (attribute.LocalName, attribute.Value);
318                         }
319                         
320                         return Result;
321                 }
322
323                 private void ReadXmlSchemaConstraints (XmlSchemaObjectCollection Constraints)
324                 {
325                         foreach (XmlSchemaObject Constraint in Constraints) {
326                                 if (Constraint is XmlSchemaUnique)
327                                         ReadXmlSchemaUnique ((XmlSchemaUnique)Constraint);
328                                 if (Constraint is XmlSchemaKeyref)
329                                         ReadXmlSchemaKeyref ((XmlSchemaKeyref)Constraint, Constraints);
330                         }
331                 }
332
333                 [MonoTODO()]
334                 private void ReadXmlSchemaUnique (XmlSchemaUnique Unique)
335                 {
336                         // FIXME: Parsing XPath
337                         string TableName = Unique.Selector.XPath;
338                         int index = TableName.IndexOf(':');
339                         if (index != -1)
340                                 TableName = TableName.Substring (index + 1);
341                         else if(TableName.StartsWith (".//"))
342                                 TableName = TableName.Substring (3);
343                         
344                         DataColumn [] Columns;
345                         DataTable Table = GetTable (TableName);
346                         if (Table != null) {
347                                 Columns = new DataColumn [Unique.Fields.Count];
348                                 int i = 0;
349                                 foreach (XmlSchemaXPath Field in Unique.Fields) {
350                                         string columnName = Field.XPath;
351                                         index = columnName.IndexOf (':');
352                                         if (index != -1)
353                                                 columnName = columnName.Substring (index + 1);
354                                         if (Table.Columns.Contains (columnName)) {
355                                                 Columns [i] = Table.Columns [columnName];
356                                                 i++;
357                                         }
358                                 }
359                                 
360                                 bool isPK = false;
361                                 // find if there is an attribute with the constraint name
362                                 // if not use the XmlSchemaUnique name.
363                                 string constraintName = Unique.Name;
364                                 if (Unique.UnhandledAttributes != null){
365                                         foreach (XmlAttribute attr in Unique.UnhandledAttributes){
366                                                 if (attr.LocalName == "ConstraintName"){
367                                                         constraintName = attr.Value;
368                                                 }
369                                                 else if (attr.LocalName == XmlConstants.PrimaryKey){
370                                                         isPK = bool.Parse(attr.Value);
371                                                 }
372
373                                         }
374                                 }
375                                 UniqueConstraint Constraint = new UniqueConstraint (constraintName, Columns, isPK);
376                                 Table.Constraints.Add (Constraint);
377                         }
378                 }
379
380                 [MonoTODO()]
381                 private void ReadXmlSchemaKeyref (XmlSchemaKeyref KeyRef, XmlSchemaObjectCollection collection) {
382                         
383                         if (DSet == null) return;       // Ignore relations for table-only schemas
384                         
385                         string TableName = KeyRef.Selector.XPath;
386                         int index = TableName.IndexOf(':');
387                         if (index != -1)
388                                 TableName = TableName.Substring (index + 1);
389                         else if (TableName.StartsWith (".//"))
390                                 TableName = TableName.Substring (3);
391                         DataColumn [] Columns;
392                         DataTable Table = GetTable (TableName);
393                         if (Table != null) {
394                                 Columns = new DataColumn [KeyRef.Fields.Count];
395                                 int i = 0;
396                                 foreach (XmlSchemaXPath Field in KeyRef.Fields) {
397                                         string columnName = Field.XPath;
398                                         index = columnName.IndexOf (':');
399                                         if (index != -1)
400                                                 columnName = columnName.Substring (index + 1);
401                                         if (Table.Columns.Contains (columnName)) {
402                                                 Columns [i] = Table.Columns [columnName];
403                                                 i++;
404                                         }
405                                 }
406                                 string name = KeyRef.Refer.Name;
407                                 // get the unique constraint for the releation
408                                 UniqueConstraint constraint = GetDSConstraint(name, collection);
409                                 // generate the FK.
410                                 ForeignKeyConstraint fkConstraint = new ForeignKeyConstraint(constraint.Columns, Columns);
411                                 Table.Constraints.Add (fkConstraint);
412                                 // generate the relation.
413                                 DataRelation relation = new DataRelation(KeyRef.Name, constraint.Columns, Columns, false);
414                                 if (KeyRef.UnhandledAttributes != null){
415                                         foreach (XmlAttribute attr in KeyRef.UnhandledAttributes){
416                                                 if (attr.LocalName == "IsNested"){
417                                                         if (attr.Value == "true")
418                                                                 relation.Nested = true;
419                                                 }
420                                         }
421                                 }
422
423                                 DSet.Relations.Add(relation);
424                         }
425                 }
426                 
427                 // get the unique constraint for the relation.
428                 // name - the name of the XmlSchemaUnique element
429                 private UniqueConstraint GetDSConstraint(string name, XmlSchemaObjectCollection collection)
430                 {
431                         // find the element in the constraint collection.
432                         foreach (XmlSchemaObject shemaObj in collection){
433                                 if (shemaObj is XmlSchemaUnique){
434                                         XmlSchemaUnique unique = (XmlSchemaUnique) shemaObj;
435                                         if (unique.Name == name){
436                                                 string tableName = unique.Selector.XPath;
437                                                 int index = tableName.IndexOf (':');
438                                                 if (index != -1)
439                                                         tableName = tableName.Substring (index + 1);
440                                                 else if (tableName.StartsWith (".//"))
441                                                         tableName = tableName.Substring (3);
442                                                 
443                                                 // find the table in the dataset.
444                                                 DataTable table = GetTable (tableName);
445                                                 if (table != null){
446                                                         
447                                                         string constraintName = unique.Name;
448                                                         // find if there is an attribute with the constraint name
449                                                         // if not use the XmlSchemaUnique name.
450                                                         if (unique.UnhandledAttributes != null){
451                                                                 foreach (XmlAttribute attr in unique.UnhandledAttributes){
452                                                                         if (attr.LocalName == "ConstraintName"){
453                                                                                 constraintName = attr.Value;
454                                                                                 break;
455                                                                         }
456                                                                 }
457                                                         }
458                                                         if (table.Constraints.Contains(constraintName))
459                                                                 return (UniqueConstraint)table.Constraints[constraintName];
460                                                 }
461
462                                         }
463                                 }
464                         }
465                         return null;
466                 }
467
468
469                 #endregion // Private methods
470
471                 #region Private listeners
472
473                 private void OnXmlSchemaValidation (object sender, ValidationEventArgs args)
474                 {
475                         ;
476                 }
477
478                 #endregion // Private listeners
479
480                 #region Private TypeReaders
481
482                 // Reads XmlSchemaType
483                 private void ReadXmlSchemaType (XmlSchemaType SchemaType)
484                 {
485                         ReadXmlSchemaType (SchemaType, (DataTable)null);
486                 }
487
488                 // Reads XmlSchemaType and decides is it Complex or Simple and continue reading those types
489                 private void ReadXmlSchemaType (XmlSchemaType SchemaType, DataTable Table)
490                 {
491                         if (SchemaType is XmlSchemaComplexType)
492                                 ReadXmlSchemaComplexType ((XmlSchemaComplexType)SchemaType, Table);
493                         else if (SchemaType is XmlSchemaSimpleType)
494                                 ReadXmlSchemaSimpleType ((XmlSchemaSimpleType)SchemaType, Table);
495                 }
496
497                 // Same as above but with DataColumn
498                 private void ReadXmlSchemaType (XmlSchemaType SchemaType, DataColumn Column)
499                 {
500                         if (SchemaType is XmlSchemaComplexType)
501                                 ReadXmlSchemaComplexType ((XmlSchemaComplexType)SchemaType, Column);
502                         else if (SchemaType is XmlSchemaSimpleType)
503                                 ReadXmlSchemaSimpleType ((XmlSchemaSimpleType)SchemaType, Column);
504                 }
505
506                 #endregion // PrivateTypeReader
507
508                 #region TypeReaderHelppers
509
510                 private void ReadXmlSchemaSimpleType (XmlSchemaSimpleType SimpleType, DataColumn Column)
511                 {
512                         // Read Contents
513                         if (SimpleType.Content is XmlSchemaSimpleTypeRestriction)
514                                 ReadXmlSchemaSimpleTypeRestriction ((XmlSchemaSimpleTypeRestriction)SimpleType.Content, Column);
515                 }
516
517                 [MonoTODO]
518                 private void ReadXmlSchemaSimpleType (XmlSchemaSimpleType SimpleType, DataTable Table)
519                 {
520                         // TODO: Is it possible that Table-element have simpletype???
521                 }
522
523                 [MonoTODO]
524                 private void ReadXmlSchemaSimpleTypeRestriction (XmlSchemaSimpleTypeRestriction Restriction, DataColumn Column)
525                 {
526                         foreach (XmlSchemaObject Facet in Restriction.Facets) {
527                                 
528                                 // FIXME: I dont know are everyone of these needed but, let them be here for now
529                                 if (Facet is XmlSchemaMaxLengthFacet) 
530                                         Column.MaxLength = Int32.Parse(((XmlSchemaFacet)Facet).Value);
531                                 //else if (Facet is XmlSchemaMinLengthFacet) 
532                                 //      ;
533                                 //else if (Facet is XmlSchemaLengthFacet)
534                                 //      ;
535                                 //else if (Facet is XmlSchemaPatternFacet)
536                                 //      ;
537                                 //else if (Facet is XmlSchemaEnumerationFacet)
538                                 //      ;
539                                 //else if (Facet is XmlSchemaMaxInclusiveFacet)
540                                 //      ;
541                                 //else if (Facet is XmlSchemaMaxExclusiveFacet)
542                                 //      ;
543                                 //else if (Facet is XmlSchemaMinInclusiveFacet)
544                                 //      ;
545                                 //else if (Facet is XmlSchemaMinExclusiveFacet)
546                                 //      ;
547                                 //else if (Facet is XmlSchemaFractionDigitsFacet)
548                                 //      ;
549                                 //else if (Facet is XmlSchemaTotalDigitsFacet)
550                                 //      ;
551                                 //else if (Facet is XmlSchemaWhiteSpaceFacet)
552                                 //      ;
553                         }
554                 }
555
556                 [MonoTODO]
557                 private void ReadXmlSchemaComplexType (XmlSchemaComplexType Type, DataColumn Column)
558                 {
559                         // TODO: is it possible that column-element have complextype
560                 }
561
562                 // Reads XmlSchemaComplexType with DataTable
563                 private void ReadXmlSchemaComplexType (XmlSchemaComplexType Type, DataTable Table)
564                 {
565                         XmlSchemaComplexType ComplexType = Type as XmlSchemaComplexType;
566                         
567                         if (ComplexType.Name != null && ComplexType.Name != string.Empty) {
568
569                                 if (ElementCollection.Contains (ComplexType.Name)) {
570
571                                         if (ComplexType.Particle is XmlSchemaChoice) {
572                                                 ReadXmlSchemaChoice (ComplexType.Particle as XmlSchemaChoice);
573                                         }
574                                         else if (ComplexType.Particle is XmlSchemaSequence) {
575
576                                                 DataTable TempTable = ElementCollection [ComplexType.Name] as DataTable;
577                                                 ElementCollection.Remove (ComplexType.Name);
578                                                 ReadXmlSchemaSequence (ComplexType.Particle as XmlSchemaSequence, TempTable);
579                                         }
580                                 }
581                                 else if (ComplexType.Name != null && !TypeCollection.Contains (ComplexType.Name)) {
582                                         TypeCollection.Add (ComplexType.Name, ComplexType);
583                                 } 
584                                 else {
585
586                                         // If we are here it means that types of elements are Tables :-P
587                                         if (ComplexType.Particle is XmlSchemaSequence)
588                                                 ReadXmlSchemaSequence (ComplexType.Particle as XmlSchemaSequence, Table);
589                                 }
590
591                         }
592                         else {
593                                 XmlSchemaParticle Particle;
594                                 if ((Particle = ComplexType.Particle as XmlSchemaChoice) != null) {
595                                         ReadXmlSchemaChoice (Particle as XmlSchemaChoice);
596                                 }
597                                 else if ((Particle = ComplexType.Particle as XmlSchemaSequence) != null) {
598                                         ReadXmlSchemaSequence (Particle as XmlSchemaSequence, Table);
599                                 }
600                                 
601                                 // read columns if they were written as simplecontent.
602                                 XmlSchemaSimpleContent simpleContent;
603                                 if ((simpleContent = ComplexType.ContentModel as XmlSchemaSimpleContent) != null){
604                                         ReadColumn (simpleContent, Table);
605                                 }
606                                 
607                                 // read columns if they were written as attributes
608                                 if (ComplexType.Attributes != null) {
609                                 
610                                         foreach (XmlSchemaObject sobj in ComplexType.Attributes) {
611                                                 if (sobj is XmlSchemaAttribute)
612                                                         ReadColumn ((XmlSchemaAttribute)sobj, Table);
613                                         }
614                                 }
615                         }
616                 }
617
618                 private void ReadColumn (XmlSchemaSimpleContent simpleContent, DataTable Table)
619                 {
620                         DataColumn Column = new DataColumn ();
621                         
622
623                         if (simpleContent.UnhandledAttributes != null) {
624                                 
625                                 foreach (XmlAttribute Attr in simpleContent.UnhandledAttributes) {
626                                         switch (Attr.LocalName) {
627                                                 
628                                         case XmlConstants.ColumnName:
629                                                 Column.ColumnName = Attr.Value;
630                                                 break;
631                                         default:
632                                                 break;
633                                         }
634                                 }
635                         }\r
636                         \r
637                         \r
638                         XmlSchemaSimpleContentExtension extension;\r
639                         if ((extension = simpleContent.Content as XmlSchemaSimpleContentExtension) != null) {\r
640                                 Column.DataType = GetColumnType (extension.BaseTypeName.Name);  \r
641                         }\r
642 \r
643                         Table.Columns.Add (Column);
644                 }
645
646                 private void ReadColumn (XmlSchemaAttribute schemaAttribute, DataTable table)
647                 {
648                         DataColumn column = new DataColumn (schemaAttribute.Name);
649                         column.DataType = GetColumnType (schemaAttribute.SchemaTypeName.Name);
650                         table.Columns.Add (column);
651                 }
652                 
653                 DataTable GetTable (string name)
654                 {
655                         if (DSet != null)
656                                 return DSet.Tables [name];
657                         else if (name == table.TableName) 
658                                 return table;
659                         else
660                                 throw new InvalidOperationException ("Schema not valid for table '" + table.TableName + "'");
661                 }
662                 
663                 #endregion // TypeReaderHelppers
664         }
665 }
666