2 // System.Data/DataSet.cs
5 // Christopher Podurgiel <cpodurgiel@msn.com>
6 // Daniel Morgan <danmorg@sc.rr.com>
7 // Rodrigo Moya <rodrigo@ximian.com>
8 // Stuart Caborn <stuart.caborn@virgin.net>
9 // Tim Coleman (tim@timcoleman.com)
10 // Ville Palo <vi64pa@koti.soon.fi>
12 // (C) Ximian, Inc. 2002
13 // Copyright (C) Tim Coleman, 2002
17 using System.Collections;
18 using System.ComponentModel;
19 using System.Globalization;
20 using System.Threading;
22 using System.Runtime.Serialization;
24 using System.Xml.Schema;
26 namespace System.Data {
28 /// an in-memory cache of data
32 [DefaultProperty ("DataSetName")]
34 public class DataSet : MarshalByValueComponent, IListSource,
35 ISupportInitialize, ISerializable {
36 private string dataSetName;
37 private string _namespace = "";
38 private string prefix;
39 private bool caseSensitive;
40 private bool enforceConstraints = true;
41 private DataTableCollection tableCollection;
42 private DataRelationCollection relationCollection;
43 private PropertyCollection properties;
44 private DataViewManager defaultView;
45 private CultureInfo locale;
49 public DataSet() : this ("NewDataSet") {
52 public DataSet(string name) {
54 tableCollection = new DataTableCollection (this);
55 relationCollection = new DataRelationCollection.DataSetRelationCollection (this);
56 properties = new PropertyCollection();
60 protected DataSet(SerializationInfo info, StreamingContext context) : this () {
61 throw new NotImplementedException ();
64 #endregion // Constructors
66 #region Public Properties
68 [DataCategory ("Data")]
69 [DataSysDescription ("Indicates whether comparing strings within the DataSet is case sensitive.")]
70 [DefaultValue (false)]
71 public bool CaseSensitive {
72 get { return caseSensitive; }
74 foreach (DataTable T in Tables) {
75 if (T.VirginCaseSensitive)
76 T.CaseSensitive = value;
79 caseSensitive = value;
83 [DataCategory ("Data")]
84 [DataSysDescription ("The name of this DataSet.")]
86 public string DataSetName {
87 get { return dataSetName; }
88 set { dataSetName = value; }
91 [DataSysDescription ("Indicates a custom \"view\" of the data contained by the DataSet. This view allows filtering, searching, and navigating through the custom data view.")]
93 public DataViewManager DefaultViewManager {
95 if (defaultView == null)
96 defaultView = new DataViewManager (this);
101 [DataSysDescription ("Indicates whether constraint rules are to be followed.")]
102 [DefaultValue (true)]
103 public bool EnforceConstraints {
104 get { return enforceConstraints; }
105 set { enforceConstraints = value; }
109 [DataCategory ("Data")]
110 [DataSysDescription ("The collection that holds custom user information.")]
111 public PropertyCollection ExtendedProperties {
112 get { return properties; }
116 [DataSysDescription ("Indicates that the DataSet has errors.")]
117 public bool HasErrors {
120 throw new NotImplementedException ();
124 [DataCategory ("Data")]
125 [DataSysDescription ("Indicates a locale under which to compare strings within the DataSet.")]
126 public CultureInfo Locale {
131 if (locale == null || !locale.Equals(value)) {
132 // TODO: check if the new locale is valid
133 // TODO: update locale of all tables
139 public void Merge (DataRow[] rows)
141 Merge (rows, false, MissingSchemaAction.Add);
144 public void Merge (DataSet dataSet)
146 Merge (dataSet, false, MissingSchemaAction.Add);
149 public void Merge (DataTable table)
151 Merge (table, false, MissingSchemaAction.Add);
154 public void Merge (DataSet dataSet, bool preserveChanges)
156 Merge (dataSet, preserveChanges, MissingSchemaAction.Add);
160 public void Merge (DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction)
162 throw new NotImplementedException();
166 public void Merge (DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction)
168 throw new NotImplementedException();
172 public void Merge (DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction)
174 throw new NotImplementedException();
177 [DataCategory ("Data")]
178 [DataSysDescription ("Indicates the XML uri namespace for the root element pointed at by this DataSet.")]
180 public string Namespace {
182 get { return _namespace; }
185 //TODO - trigger an event if this happens?
190 [DataCategory ("Data")]
191 [DataSysDescription ("Indicates the prefix of the namespace used for this DataSet.")]
193 public string Prefix {
195 get { return prefix; }
198 //TODO - trigger an event if this happens?
203 [DataCategory ("Data")]
204 [DataSysDescription ("The collection that holds the relations for this DatSet.")]
205 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
206 public DataRelationCollection Relations {
208 return relationCollection;
213 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
214 public override ISite Site {
217 throw new NotImplementedException ();
222 throw new NotImplementedException ();
226 [DataCategory ("Data")]
227 [DataSysDescription ("The collection that holds the tables for this DataSet.")]
228 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
229 public DataTableCollection Tables {
230 get { return tableCollection; }
233 #endregion // Public Properties
235 #region Public Methods
238 public void AcceptChanges()
240 foreach (DataTable tempTable in tableCollection)
241 tempTable.AcceptChanges ();
246 throw new NotImplementedException ();
249 public virtual DataSet Clone()
251 DataSet Copy = new DataSet ();
252 CopyProperties (Copy);
254 foreach (DataTable Table in Tables) {
255 Copy.Tables.Add (Table.Clone ());
261 // Copies both the structure and data for this DataSet.
262 public DataSet Copy()
264 DataSet Copy = new DataSet ();
265 CopyProperties (Copy);
267 // Copy DatSet's tables
268 foreach (DataTable Table in Tables) {
269 Copy.Tables.Add (Table.Copy ());
276 private void CopyProperties (DataSet Copy)
278 Copy.CaseSensitive = CaseSensitive;
279 //Copy.Container = Container
280 Copy.DataSetName = DataSetName;
281 //Copy.DefaultViewManager
283 Copy.EnforceConstraints = EnforceConstraints;
284 //Copy.ExtendedProperties
286 //Copy.Locale = Locale;
287 Copy.Namespace = Namespace;
288 Copy.Prefix = Prefix;
289 //Copy.Relations = Relations;
294 public DataSet GetChanges()
296 throw new NotImplementedException ();
300 public DataSet GetChanges(DataRowState rowStates)
302 throw new NotImplementedException ();
305 public string GetXml()
307 StringWriter Writer = new StringWriter ();
308 WriteXml (Writer, XmlWriteMode.IgnoreSchema);
309 return Writer.ToString ();
312 public string GetXmlSchema()
314 StringWriter Writer = new StringWriter ();
315 WriteXmlSchema (Writer);
316 return Writer.ToString ();
320 public bool HasChanges()
322 throw new NotImplementedException ();
326 public bool HasChanges(DataRowState rowState)
328 throw new NotImplementedException ();
332 public void InferXmlSchema(XmlReader reader, string[] nsArray)
336 public void InferXmlSchema(Stream stream, string[] nsArray)
338 InferXmlSchema (new XmlTextReader(stream), nsArray);
341 public void InferXmlSchema(TextReader reader, string[] nsArray)
343 InferXmlSchema (new XmlTextReader(reader), nsArray);
346 public void InferXmlSchema(string fileName, string[] nsArray)
348 XmlTextReader reader = new XmlTextReader(fileName);
350 InferXmlSchema (reader, nsArray);
356 public virtual void RejectChanges()
358 throw new NotImplementedException ();
361 public virtual void Reset()
363 throw new NotImplementedException ();
366 public void WriteXml(Stream stream)
368 XmlWriter writer = new XmlTextWriter(stream, null );
374 /// Writes the current data for the DataSet to the specified file.
376 /// <param name="filename">Fully qualified filename to write to</param>
377 public void WriteXml(string fileName)
379 XmlWriter writer = new XmlTextWriter(fileName, null );
384 public void WriteXml(TextWriter writer)
386 XmlWriter xwriter = new XmlTextWriter(writer );
391 public void WriteXml(XmlWriter writer)
393 WriteXml( writer, XmlWriteMode.IgnoreSchema );
396 public void WriteXml(Stream stream, XmlWriteMode mode)
398 XmlWriter writer = new XmlTextWriter(stream, null );
400 WriteXml( writer, mode );
403 public void WriteXml(string fileName, XmlWriteMode mode)
405 XmlWriter writer = new XmlTextWriter(fileName, null );
407 WriteXml( writer, mode );
410 public void WriteXml(TextWriter writer, XmlWriteMode mode)
412 XmlWriter xwriter = new XmlTextWriter(writer);
414 WriteXml( xwriter, mode );
417 public void WriteXml(XmlWriter writer, XmlWriteMode mode)
419 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
420 WriteStartElement( writer, mode, Namespace, Prefix, DataSetName );
422 if( mode == XmlWriteMode.WriteSchema )
424 DoWriteXmlSchema( writer );
427 //Write out each table in order, providing it is not
428 //part of another table structure via a nested parent relationship
429 foreach( DataTable table in Tables )
431 bool isTopLevel = true;
432 foreach( DataRelation rel in table.ParentRelations )
443 WriteTable( writer, table, mode );
447 writer.WriteEndElement();
450 public void WriteXmlSchema(Stream stream)
452 XmlWriter writer = new XmlTextWriter(stream, null );
454 WriteXmlSchema( writer );
457 public void WriteXmlSchema(string fileName)
459 XmlWriter writer = new XmlTextWriter( fileName, null );
461 WriteXmlSchema( writer );
464 public void WriteXmlSchema(TextWriter writer)
466 XmlWriter xwriter = new XmlTextWriter( writer );
468 WriteXmlSchema( xwriter );
471 public void WriteXmlSchema(XmlWriter writer)
473 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
474 //Create a skeleton doc and then write the schema
475 //proper which is common to the WriteXml method in schema mode
476 writer.WriteStartDocument();
478 DoWriteXmlSchema( writer );
480 writer.WriteEndDocument();
483 public void ReadXmlSchema(Stream stream)
485 XmlReader reader = new XmlTextReader( stream, null );
486 ReadXmlSchema( reader);
489 public void ReadXmlSchema(string str)
491 XmlReader reader = new XmlTextReader( str );
492 ReadXmlSchema( reader );
495 public void ReadXmlSchema(TextReader treader)
497 XmlReader reader = new XmlTextReader( treader );
498 ReadXmlSchema( reader );
501 public void ReadXmlSchema(XmlReader reader)
503 XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
504 SchemaMapper.Read (reader);
507 public XmlReadMode ReadXml (Stream stream)
509 return ReadXml (new XmlTextReader (stream));
512 public XmlReadMode ReadXml (string str)
514 return ReadXml (new XmlTextReader (str));
517 public XmlReadMode ReadXml (TextReader reader)
519 return ReadXml (new XmlTextReader (reader));
522 public XmlReadMode ReadXml (XmlReader r)
524 XmlDataLoader Loader = new XmlDataLoader (this);
525 // FIXME: somekinda exception?
527 return XmlReadMode.Auto; // FIXME
530 * If document is diffgram we will use diffgram
532 if (r.LocalName == "diffgram")
533 return ReadXml (r, XmlReadMode.DiffGram);
536 * If we already have a schema, or the document
537 * contains an in-line schema, sets XmlReadMode to ReadSchema.
540 // FIXME: is this always true: "if we have tables we have to have schema also"
541 if (Tables.Count > 0)
542 return ReadXml (r, XmlReadMode.ReadSchema);
545 * If we dont have a schema yet and document
546 * contains no inline-schema mode is XmlReadMode.InferSchema
549 return ReadXml (r, XmlReadMode.InferSchema);
553 public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
555 return ReadXml (new XmlTextReader (stream), mode);
558 public XmlReadMode ReadXml (string str, XmlReadMode mode)
560 return ReadXml (new XmlTextReader (str), mode);
563 public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
565 return ReadXml (new XmlTextReader (reader), mode);
569 public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
571 XmlReadMode Result = XmlReadMode.Auto;
573 if (mode == XmlReadMode.DiffGram) {
574 XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
575 DiffLoader.Load (reader);
576 Result = XmlReadMode.DiffGram;
579 XmlDataLoader Loader = new XmlDataLoader (this);
580 Result = Loader.LoadData (reader, mode);
586 #endregion // Public Methods
588 #region Public Events
590 [DataCategory ("Action")]
591 [DataSysDescription ("Occurs when it is not possible to merge schemas for two tables with the same name.")]
592 public event MergeFailedEventHandler MergeFailed;
594 #endregion // Public Events
602 #endregion Destructors
604 #region IListSource methods
605 IList IListSource.GetList ()
607 return DefaultViewManager;
610 bool IListSource.ContainsListCollection {
615 #endregion IListSource methods
617 #region ISupportInitialize methods
618 public void BeginInit ()
620 throw new NotImplementedException ();
623 public void EndInit ()
625 throw new NotImplementedException ();
629 #region ISerializable
630 void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
632 throw new NotImplementedException ();
636 #region Protected Methods
637 protected void GetSerializationData(SerializationInfo info, StreamingContext context)
639 string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
640 if (s != null) ReadXmlSerializable (new XmlTextReader(new StringReader(s)));
644 protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable()
646 return null; // FIXME
649 protected virtual void ReadXmlSerializable(XmlReader reader)
651 ReadXml(reader, XmlReadMode.DiffGram); // FIXME
654 protected virtual bool ShouldSerializeRelations ()
659 protected virtual bool ShouldSerializeTables ()
665 protected internal virtual void OnPropertyChanging (PropertyChangedEventArgs pcevent)
670 protected virtual void OnRemoveRelation (DataRelation relation)
675 protected virtual void OnRemoveTable (DataTable table)
680 protected internal void RaisePropertyChanging (string name)
685 #region Private Xml Serialisation
687 private string WriteObjectXml( object o ) {
688 switch (Type.GetTypeCode (o.GetType ())) {
689 case TypeCode.Boolean:
690 return XmlConvert.ToString ((Boolean) o);
692 return XmlConvert.ToString ((Byte) o);
694 return XmlConvert.ToString ((Char) o);
695 case TypeCode.DateTime:
696 return XmlConvert.ToString ((DateTime) o);
697 case TypeCode.Decimal:
698 return XmlConvert.ToString ((Decimal) o);
699 case TypeCode.Double:
700 return XmlConvert.ToString ((Double) o);
702 return XmlConvert.ToString ((Int16) o);
704 return XmlConvert.ToString ((Int32) o);
706 return XmlConvert.ToString ((Int64) o);
708 return XmlConvert.ToString ((SByte) o);
709 case TypeCode.Single:
710 return XmlConvert.ToString ((Single) o);
711 case TypeCode.UInt16:
712 return XmlConvert.ToString ((UInt16) o);
713 case TypeCode.UInt32:
714 return XmlConvert.ToString ((UInt32) o);
715 case TypeCode.UInt64:
716 return XmlConvert.ToString ((UInt64) o);
718 if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
719 if (o is Guid) return XmlConvert.ToString ((Guid) o);
723 private void WriteTable( XmlWriter writer, DataTable table, XmlWriteMode mode )
725 DataRow[] rows = new DataRow [table.Rows.Count];
726 table.Rows.CopyTo (rows, 0);
727 WriteTable (writer, rows, mode);
730 private void WriteTable( XmlWriter writer, DataRow[] rows, XmlWriteMode mode )
732 //The columns can be attributes, hidden, elements, or simple content
733 //There can be 0-1 simple content cols or 0-* elements
734 System.Collections.ArrayList atts;
735 System.Collections.ArrayList elements;
736 DataColumn simple = null;
738 if (rows.Length == 0) return;
739 DataTable table = rows[0].Table;
740 SplitColumns( table, out atts, out elements, out simple );
742 foreach( DataRow row in rows )
744 //sort out the namespacing
745 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
747 // First check are all the rows null. If they are we just write empty element
748 bool AllNulls = true;
749 foreach (DataColumn dc in table.Columns) {
751 if (row [dc.ColumnName] != DBNull.Value) {
757 // If all of the columns were null, we have to write empty element
759 writer.WriteElementString (table.TableName, "");
763 WriteStartElement( writer, mode, nspc, table.Prefix, table.TableName );
765 foreach( DataColumn col in atts )
767 WriteAttributeString( writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col].ToString() );
772 writer.WriteString( WriteObjectXml(row[simple]) );
776 foreach( DataColumn col in elements )
778 string colnspc = nspc;
779 object rowObject = row [col];
781 if (rowObject == null || rowObject == DBNull.Value)
784 if( col.Namespace != null )
786 colnspc = col.Namespace;
789 //TODO check if I can get away with write element string
790 WriteStartElement( writer, mode, colnspc, col.Prefix, col.ColumnName );
791 writer.WriteString( WriteObjectXml(rowObject) );
792 writer.WriteEndElement();
796 foreach (DataRelation relation in table.ChildRelations) {
797 if (relation.Nested) {
798 WriteTable (writer, row.GetChildRows(relation), mode);
802 writer.WriteEndElement();
807 private void WriteStartElement( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name )
811 case XmlWriteMode.WriteSchema:
812 if( nspc == null || nspc == "" )
814 writer.WriteStartElement( name );
816 else if( prefix != null )
818 writer.WriteStartElement(prefix, name, nspc );
822 writer.WriteStartElement( writer.LookupPrefix( nspc ), name, nspc );
825 case XmlWriteMode.DiffGram:
826 throw new NotImplementedException();
828 writer.WriteStartElement(name );
833 private void WriteAttributeString( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue )
837 case XmlWriteMode.WriteSchema:
838 writer.WriteAttributeString(prefix, name, nspc );
840 case XmlWriteMode.DiffGram:
841 throw new NotImplementedException();
843 writer.WriteAttributeString(name, stringValue );
848 private void DoWriteXmlSchema( XmlWriter writer )
850 //Create the root element and declare all the namespaces etc
851 writer.WriteStartElement(XmlConstants.SchemaPrefix, XmlConstants.SchemaElement,
852 XmlConstants.SchemaNamespace );
853 writer.WriteAttributeString( XmlConstants.TargetNamespace, Namespace );
854 writer.WriteAttributeString( "xmlns:" + XmlConstants.TnsPrefix, Namespace );
855 writer.WriteAttributeString( "xmlns", Namespace );
856 writer.WriteAttributeString( "xmlns:" + XmlConstants.MsdataPrefix,
857 XmlConstants.MsdataNamespace );
858 //Set up the attribute and element forms.
859 //TODO - is it possible to change this?
860 //I couldn't spot if it was so I assumed
861 //that this is set to qualified all round basedon the MS output
862 writer.WriteAttributeString( XmlConstants.AttributeFormDefault,
863 XmlConstants.Qualified );
864 writer.WriteAttributeString( XmlConstants.ElementFormDefault,
865 XmlConstants.Qualified );
868 //<xs:element name="DSName msdata:IsDataSet="true" msdata:Locale="machine-locale">
869 //Create the data set element
870 //All the tables are represented as choice elements in an unlimited series
871 writer.WriteStartElement( XmlConstants.SchemaPrefix,
872 XmlConstants.Element,
873 XmlConstants.SchemaNamespace );
875 writer.WriteAttributeString( XmlConstants.Name, DataSetName );
876 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace, "true" );
877 //FIXME - sort out the locale string!
879 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace, Thread.CurrentThread.CurrentCulture.Name);
882 writer.WriteStartElement( XmlConstants.SchemaPrefix,
883 XmlConstants.ComplexType,
884 XmlConstants.SchemaNamespace );
886 //<xs:choice maxOccurs="unbounded">
887 writer.WriteStartElement( XmlConstants.SchemaPrefix,
889 XmlConstants.SchemaNamespace );
891 writer.WriteAttributeString( XmlConstants.MaxOccurs, XmlConstants.Unbounded );
894 //Write out schema for each table in order, providing it is not
895 //part of another table structure via a nested parent relationship
896 foreach( DataTable table in Tables )
898 bool isTopLevel = true;
899 foreach( DataRelation rel in table.ParentRelations )
910 WriteTableSchema( writer, table );
915 writer.WriteEndElement();
917 writer.WriteEndElement();
919 //TODO - now add in the relationships as key and unique constraints etc
922 writer.WriteEndElement();
926 writer.WriteEndElement();
929 private void WriteTableSchema( XmlWriter writer, DataTable table )
935 SplitColumns( table,out atts, out elements, out simple );
937 //<xs:element name="TableName">
938 writer.WriteStartElement( XmlConstants.SchemaPrefix,
939 XmlConstants.Element,
940 XmlConstants.SchemaNamespace );
942 writer.WriteAttributeString( XmlConstants.Name, table.TableName );
945 writer.WriteStartElement( XmlConstants.SchemaPrefix,
946 XmlConstants.ComplexType,
947 XmlConstants.SchemaNamespace );
949 //TODO - what about the simple content?
950 if( elements.Count == 0 )
955 //A sequence of element types or a simple content node
957 writer.WriteStartElement( XmlConstants.SchemaPrefix,
958 XmlConstants.Sequence,
959 XmlConstants.SchemaNamespace );
960 foreach( DataColumn col in elements )
962 //<xs:element name=ColumnName type=MappedType Ordinal=index>
963 writer.WriteStartElement( XmlConstants.SchemaPrefix,
964 XmlConstants.Element,
965 XmlConstants.SchemaNamespace );
967 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
969 if (col.ColumnName != col.Caption && col.Caption != string.Empty)
970 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Caption,
971 XmlConstants.MsdataNamespace, col.Caption);
973 if (col.DefaultValue.ToString () != string.Empty)
974 writer.WriteAttributeString( XmlConstants.Default, col.DefaultValue.ToString ());
976 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
978 if( col.AllowDBNull )
980 writer.WriteAttributeString( XmlConstants.MinOccurs, "0" );
983 //writer.WriteAttributeString( XmlConstants.MsdataPrefix,
984 // XmlConstants.Ordinal,
985 // XmlConstants.MsdataNamespace,
986 // col.Ordinal.ToString() );
988 // Write SimpleType if column have MaxLength
989 if (col.MaxLength > -1) {
991 WriteTableSimpleType (writer, col);
996 writer.WriteEndElement();
999 writer.WriteEndElement();
1002 //Then a list of attributes
1003 foreach( DataColumn col in atts )
1005 //<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
1006 writer.WriteStartElement( XmlConstants.SchemaPrefix,
1007 XmlConstants.Attribute,
1008 XmlConstants.SchemaNamespace );
1010 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
1011 writer.WriteAttributeString( XmlConstants.Form, XmlConstants.Unqualified );
1012 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
1014 writer.WriteEndElement();
1018 writer.WriteEndElement();
1021 writer.WriteEndElement();
1024 private void WriteTableSimpleType (XmlWriter writer, DataColumn col)
1027 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.SimpleType,
1028 XmlConstants.SchemaNamespace);
1031 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.Restriction,
1032 XmlConstants.SchemaNamespace);
1034 writer.WriteAttributeString( XmlConstants.Base, MapType( col.DataType ) );
1037 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.MaxLength,
1038 XmlConstants.SchemaNamespace);
1039 writer.WriteAttributeString( XmlConstants.Value, col.MaxLength.ToString ());
1042 writer.WriteEndElement();
1044 writer.WriteEndElement();
1046 writer.WriteEndElement();
1050 /// Helper function to split columns into attributes elements and simple
1053 private void SplitColumns( DataTable table,
1055 out ArrayList elements,
1056 out DataColumn simple)
1058 //The columns can be attributes, hidden, elements, or simple content
1059 //There can be 0-1 simple content cols or 0-* elements
1060 atts = new System.Collections.ArrayList();
1061 elements = new System.Collections.ArrayList();
1064 //Sort out the columns
1065 foreach( DataColumn col in table.Columns )
1067 switch( col.ColumnMapping )
1069 case MappingType.Attribute:
1072 case MappingType.Element:
1073 elements.Add( col );
1075 case MappingType.SimpleContent:
1076 if( simple != null )
1078 throw new System.InvalidOperationException( "There may only be one simple content element" );
1083 //ignore Hidden elements
1090 private string MapType( Type type )
1092 string Result = "xs:string";
1094 // TODO: More types to map?
1096 if (typeof (string) == type)
1097 Result = "xs:string";
1098 else if (typeof (short) == type)
1099 Result = "xs:short";
1100 else if (typeof (int) == type)
1102 else if (typeof (long) == type)
1104 else if (typeof (bool) == type)
1105 Result = "xs:boolean";
1106 else if (typeof (byte) == type)
1107 Result = "xs:unsignedByte";
1108 else if (typeof (char) == type)
1110 else if (typeof (DateTime) == type)
1111 Result = "xs:dateTime";
1112 else if (typeof (decimal) == type)
1113 Result = "xs:decimal";
1114 else if (typeof (double) == type)
1115 Result = "xs:double";
1116 else if (typeof (sbyte) == type)
1117 Result = "xs:sbyte";
1118 else if (typeof (Single) == type)
1119 Result = "xs:float";
1120 else if (typeof (TimeSpan) == type)
1121 Result = "xs:duration";
1122 else if (typeof (ushort) == type)
1123 Result = "xs:usignedShort";
1124 else if (typeof (uint) == type)
1125 Result = "xs:unsignedInt";
1126 else if (typeof (ulong) == type)
1127 Result = "xs:unsignedLong";
1132 #endregion //Private Xml Serialisation