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);
155 public void Merge (DataSet dataSet, bool preserveChanges)
157 Merge (dataSet, preserveChanges, MissingSchemaAction.Add);
161 public void Merge (DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction)
163 throw new NotImplementedException();
167 public void Merge (DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction)
169 throw new NotImplementedException();
173 public void Merge (DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction)
175 throw new NotImplementedException();
178 [DataCategory ("Data")]
179 [DataSysDescription ("Indicates the XML uri namespace for the root element pointed at by this DataSet.")]
181 public string Namespace {
183 get { return _namespace; }
186 //TODO - trigger an event if this happens?
191 [DataCategory ("Data")]
192 [DataSysDescription ("Indicates the prefix of the namespace used for this DataSet.")]
194 public string Prefix {
196 get { return prefix; }
199 //TODO - trigger an event if this happens?
204 [DataCategory ("Data")]
205 [DataSysDescription ("The collection that holds the relations for this DatSet.")]
206 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
207 public DataRelationCollection Relations {
209 return relationCollection;
214 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
215 public override ISite Site {
218 throw new NotImplementedException ();
223 throw new NotImplementedException ();
227 [DataCategory ("Data")]
228 [DataSysDescription ("The collection that holds the tables for this DataSet.")]
229 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
230 public DataTableCollection Tables {
231 get { return tableCollection; }
234 #endregion // Public Properties
236 #region Public Methods
239 public void AcceptChanges()
241 foreach (DataTable tempTable in tableCollection)
242 tempTable.AcceptChanges ();
247 throw new NotImplementedException ();
250 public virtual DataSet Clone()
252 DataSet Copy = new DataSet ();
253 CopyProperties (Copy);
255 foreach (DataTable Table in Tables) {
256 Copy.Tables.Add (Table.Clone ());
262 // Copies both the structure and data for this DataSet.
263 public DataSet Copy()
265 DataSet Copy = new DataSet ();
266 CopyProperties (Copy);
268 // Copy DatSet's tables
269 foreach (DataTable Table in Tables) {
270 Copy.Tables.Add (Table.Copy ());
277 private void CopyProperties (DataSet Copy)
279 Copy.CaseSensitive = CaseSensitive;
280 //Copy.Container = Container
281 Copy.DataSetName = DataSetName;
282 //Copy.DefaultViewManager
284 Copy.EnforceConstraints = EnforceConstraints;
285 //Copy.ExtendedProperties
287 //Copy.Locale = Locale;
288 Copy.Namespace = Namespace;
289 Copy.Prefix = Prefix;
290 //Copy.Relations = Relations;
295 public DataSet GetChanges()
297 throw new NotImplementedException ();
301 public DataSet GetChanges(DataRowState rowStates)
303 throw new NotImplementedException ();
306 public string GetXml()
308 StringWriter Writer = new StringWriter ();
309 WriteXml (Writer, XmlWriteMode.IgnoreSchema);
310 return Writer.ToString ();
313 public string GetXmlSchema()
315 StringWriter Writer = new StringWriter ();
316 WriteXmlSchema (Writer);
317 return Writer.ToString ();
321 public bool HasChanges()
323 throw new NotImplementedException ();
327 public bool HasChanges(DataRowState rowState)
329 throw new NotImplementedException ();
333 public void InferXmlSchema(XmlReader reader, string[] nsArray)
337 public void InferXmlSchema(Stream stream, string[] nsArray)
339 InferXmlSchema (new XmlTextReader(stream), nsArray);
342 public void InferXmlSchema(TextReader reader, string[] nsArray)
344 InferXmlSchema (new XmlTextReader(reader), nsArray);
347 public void InferXmlSchema(string fileName, string[] nsArray)
349 XmlTextReader reader = new XmlTextReader(fileName);
351 InferXmlSchema (reader, nsArray);
357 public virtual void RejectChanges()
359 throw new NotImplementedException ();
362 public virtual void Reset()
364 throw new NotImplementedException ();
367 public void WriteXml(Stream stream)
369 XmlWriter writer = new XmlTextWriter(stream, null );
375 /// Writes the current data for the DataSet to the specified file.
377 /// <param name="filename">Fully qualified filename to write to</param>
378 public void WriteXml(string fileName)
380 XmlWriter writer = new XmlTextWriter(fileName, null );
385 public void WriteXml(TextWriter writer)
387 XmlWriter xwriter = new XmlTextWriter(writer );
392 public void WriteXml(XmlWriter writer)
394 WriteXml( writer, XmlWriteMode.IgnoreSchema );
397 public void WriteXml(Stream stream, XmlWriteMode mode)
399 XmlWriter writer = new XmlTextWriter(stream, null );
401 WriteXml( writer, mode );
404 public void WriteXml(string fileName, XmlWriteMode mode)
406 XmlWriter writer = new XmlTextWriter(fileName, null );
408 WriteXml( writer, mode );
411 public void WriteXml(TextWriter writer, XmlWriteMode mode)
413 XmlWriter xwriter = new XmlTextWriter(writer);
415 WriteXml( xwriter, mode );
418 public void WriteXml(XmlWriter writer, XmlWriteMode mode)
420 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
421 WriteStartElement( writer, mode, Namespace, Prefix, DataSetName );
423 if( mode == XmlWriteMode.WriteSchema )
425 DoWriteXmlSchema( writer );
428 //Write out each table in order, providing it is not
429 //part of another table structure via a nested parent relationship
430 foreach( DataTable table in Tables )
432 bool isTopLevel = true;
433 foreach( DataRelation rel in table.ParentRelations )
444 WriteTable( writer, table, mode );
448 writer.WriteEndElement();
451 public void WriteXmlSchema(Stream stream)
453 XmlWriter writer = new XmlTextWriter(stream, null );
455 WriteXmlSchema( writer );
458 public void WriteXmlSchema(string fileName)
460 XmlWriter writer = new XmlTextWriter( fileName, null );
462 WriteXmlSchema( writer );
465 public void WriteXmlSchema(TextWriter writer)
467 XmlWriter xwriter = new XmlTextWriter( writer );
469 WriteXmlSchema( xwriter );
472 public void WriteXmlSchema(XmlWriter writer)
474 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
475 //Create a skeleton doc and then write the schema
476 //proper which is common to the WriteXml method in schema mode
477 writer.WriteStartDocument();
479 DoWriteXmlSchema( writer );
481 writer.WriteEndDocument();
484 public void ReadXmlSchema(Stream stream)
486 XmlReader reader = new XmlTextReader( stream, null );
487 ReadXmlSchema( reader);
490 public void ReadXmlSchema(string str)
492 XmlReader reader = new XmlTextReader( str );
493 ReadXmlSchema( reader );
496 public void ReadXmlSchema(TextReader treader)
498 XmlReader reader = new XmlTextReader( treader );
499 ReadXmlSchema( reader );
502 public void ReadXmlSchema(XmlReader reader)
504 XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
505 SchemaMapper.Read (reader);
508 public XmlReadMode ReadXml (Stream stream)
510 return ReadXml (new XmlTextReader (stream));
513 public XmlReadMode ReadXml (string str)
515 return ReadXml (new XmlTextReader (str));
518 public XmlReadMode ReadXml (TextReader reader)
520 return ReadXml (new XmlTextReader (reader));
523 public XmlReadMode ReadXml (XmlReader r)
525 XmlDataLoader Loader = new XmlDataLoader (this);
526 // FIXME: somekinda exception?
528 return XmlReadMode.Auto; // FIXME
531 * If document is diffgram we will use diffgram
533 if (r.LocalName == "diffgram")
534 return ReadXml (r, XmlReadMode.DiffGram);
537 * If we already have a schema, or the document
538 * contains an in-line schema, sets XmlReadMode to ReadSchema.
541 // FIXME: is this always true: "if we have tables we have to have schema also"
542 if (Tables.Count > 0)
543 return ReadXml (r, XmlReadMode.ReadSchema);
546 * If we dont have a schema yet and document
547 * contains no inline-schema mode is XmlReadMode.InferSchema
550 return ReadXml (r, XmlReadMode.InferSchema);
554 public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
556 return ReadXml (new XmlTextReader (stream), mode);
559 public XmlReadMode ReadXml (string str, XmlReadMode mode)
561 return ReadXml (new XmlTextReader (str), mode);
564 public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
566 return ReadXml (new XmlTextReader (reader), mode);
570 public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
572 XmlReadMode Result = XmlReadMode.Auto;
574 if (mode == XmlReadMode.DiffGram) {
575 XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
576 DiffLoader.Load (reader);
577 Result = XmlReadMode.DiffGram;
580 XmlDataLoader Loader = new XmlDataLoader (this);
581 Result = Loader.LoadData (reader, mode);
587 #endregion // Public Methods
589 #region Public Events
591 [DataCategory ("Action")]
592 [DataSysDescription ("Occurs when it is not possible to merge schemas for two tables with the same name.")]
593 public event MergeFailedEventHandler MergeFailed;
595 #endregion // Public Events
603 #endregion Destructors
605 #region IListSource methods
606 IList IListSource.GetList ()
608 return DefaultViewManager;
611 bool IListSource.ContainsListCollection {
616 #endregion IListSource methods
618 #region ISupportInitialize methods
619 public void BeginInit ()
621 throw new NotImplementedException ();
624 public void EndInit ()
626 throw new NotImplementedException ();
630 #region ISerializable
631 void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
633 throw new NotImplementedException ();
637 #region Protected Methods
638 protected void GetSerializationData(SerializationInfo info, StreamingContext context)
640 string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
641 if (s != null) ReadXmlSerializable (new XmlTextReader(new StringReader(s)));
645 protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable()
647 return null; // FIXME
650 protected virtual void ReadXmlSerializable(XmlReader reader)
652 ReadXml(reader, XmlReadMode.DiffGram); // FIXME
655 protected virtual bool ShouldSerializeRelations ()
660 protected virtual bool ShouldSerializeTables ()
666 protected virtual void OnPropertyChanging (PropertyChangedEventArgs pcevent)
671 protected virtual void OnRemoveRelation (DataRelation relation)
676 protected virtual void OnRemoveTable (DataTable table)
681 protected void RaisePropertyChanging (string name)
686 #region Private Xml Serialisation
688 private string WriteObjectXml( object o ) {
689 switch (Type.GetTypeCode (o.GetType ())) {
690 case TypeCode.Boolean:
691 return XmlConvert.ToString ((Boolean) o);
693 return XmlConvert.ToString ((Byte) o);
695 return XmlConvert.ToString ((Char) o);
696 case TypeCode.DateTime:
697 return XmlConvert.ToString ((DateTime) o);
698 case TypeCode.Decimal:
699 return XmlConvert.ToString ((Decimal) o);
700 case TypeCode.Double:
701 return XmlConvert.ToString ((Double) o);
703 return XmlConvert.ToString ((Int16) o);
705 return XmlConvert.ToString ((Int32) o);
707 return XmlConvert.ToString ((Int64) o);
709 return XmlConvert.ToString ((SByte) o);
710 case TypeCode.Single:
711 return XmlConvert.ToString ((Single) o);
712 case TypeCode.UInt16:
713 return XmlConvert.ToString ((UInt16) o);
714 case TypeCode.UInt32:
715 return XmlConvert.ToString ((UInt32) o);
716 case TypeCode.UInt64:
717 return XmlConvert.ToString ((UInt64) o);
719 if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
720 if (o is Guid) return XmlConvert.ToString ((Guid) o);
724 private void WriteTable( XmlWriter writer, DataTable table, XmlWriteMode mode )
726 DataRow[] rows = new DataRow [table.Rows.Count];
727 table.Rows.CopyTo (rows, 0);
728 WriteTable (writer, rows, mode);
731 private void WriteTable( XmlWriter writer, DataRow[] rows, XmlWriteMode mode )
733 //The columns can be attributes, hidden, elements, or simple content
734 //There can be 0-1 simple content cols or 0-* elements
735 System.Collections.ArrayList atts;
736 System.Collections.ArrayList elements;
737 DataColumn simple = null;
739 if (rows.Length == 0) return;
740 DataTable table = rows[0].Table;
741 SplitColumns( table, out atts, out elements, out simple );
743 foreach( DataRow row in rows )
745 //sort out the namespacing
746 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
748 // First check are all the rows null. If they are we just write empty element
749 bool AllNulls = true;
750 foreach (DataColumn dc in table.Columns) {
752 if (row [dc.ColumnName] != DBNull.Value) {
758 // If all of the columns were null, we have to write empty element
760 writer.WriteElementString (table.TableName, "");
764 WriteStartElement( writer, mode, nspc, table.Prefix, table.TableName );
766 foreach( DataColumn col in atts )
768 WriteAttributeString( writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col].ToString() );
773 writer.WriteString( WriteObjectXml(row[simple]) );
777 foreach( DataColumn col in elements )
779 string colnspc = nspc;
780 object rowObject = row [col];
782 if (rowObject == null || rowObject == DBNull.Value)
785 if( col.Namespace != null )
787 colnspc = col.Namespace;
790 //TODO check if I can get away with write element string
791 WriteStartElement( writer, mode, colnspc, col.Prefix, col.ColumnName );
792 writer.WriteString( WriteObjectXml(rowObject) );
793 writer.WriteEndElement();
797 foreach (DataRelation relation in table.ChildRelations) {
798 if (relation.Nested) {
799 WriteTable (writer, row.GetChildRows(relation), mode);
803 writer.WriteEndElement();
808 private void WriteStartElement( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name )
812 case XmlWriteMode.WriteSchema:
813 if( nspc == null || nspc == "" )
815 writer.WriteStartElement( name );
817 else if( prefix != null )
819 writer.WriteStartElement(prefix, name, nspc );
823 writer.WriteStartElement( writer.LookupPrefix( nspc ), name, nspc );
826 case XmlWriteMode.DiffGram:
827 throw new NotImplementedException();
829 writer.WriteStartElement(name );
834 private void WriteAttributeString( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue )
838 case XmlWriteMode.WriteSchema:
839 writer.WriteAttributeString(prefix, name, nspc );
841 case XmlWriteMode.DiffGram:
842 throw new NotImplementedException();
844 writer.WriteAttributeString(name, stringValue );
849 private void DoWriteXmlSchema( XmlWriter writer )
851 //Create the root element and declare all the namespaces etc
852 writer.WriteStartElement(XmlConstants.SchemaPrefix, XmlConstants.SchemaElement,
853 XmlConstants.SchemaNamespace );
854 writer.WriteAttributeString( XmlConstants.TargetNamespace, Namespace );
855 writer.WriteAttributeString( "xmlns:" + XmlConstants.TnsPrefix, Namespace );
856 writer.WriteAttributeString( "xmlns", Namespace );
857 writer.WriteAttributeString( "xmlns:" + XmlConstants.MsdataPrefix,
858 XmlConstants.MsdataNamespace );
859 //Set up the attribute and element forms.
860 //TODO - is it possible to change this?
861 //I couldn't spot if it was so I assumed
862 //that this is set to qualified all round basedon the MS output
863 writer.WriteAttributeString( XmlConstants.AttributeFormDefault,
864 XmlConstants.Qualified );
865 writer.WriteAttributeString( XmlConstants.ElementFormDefault,
866 XmlConstants.Qualified );
869 //<xs:element name="DSName msdata:IsDataSet="true" msdata:Locale="machine-locale">
870 //Create the data set element
871 //All the tables are represented as choice elements in an unlimited series
872 writer.WriteStartElement( XmlConstants.SchemaPrefix,
873 XmlConstants.Element,
874 XmlConstants.SchemaNamespace );
876 writer.WriteAttributeString( XmlConstants.Name, DataSetName );
877 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace, "true" );
878 //FIXME - sort out the locale string!
880 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace, Thread.CurrentThread.CurrentCulture.Name);
883 writer.WriteStartElement( XmlConstants.SchemaPrefix,
884 XmlConstants.ComplexType,
885 XmlConstants.SchemaNamespace );
887 //<xs:choice maxOccurs="unbounded">
888 writer.WriteStartElement( XmlConstants.SchemaPrefix,
890 XmlConstants.SchemaNamespace );
892 writer.WriteAttributeString( XmlConstants.MaxOccurs, XmlConstants.Unbounded );
895 //Write out schema for each table in order, providing it is not
896 //part of another table structure via a nested parent relationship
897 foreach( DataTable table in Tables )
899 bool isTopLevel = true;
900 foreach( DataRelation rel in table.ParentRelations )
911 WriteTableSchema( writer, table );
916 writer.WriteEndElement();
918 writer.WriteEndElement();
920 //TODO - now add in the relationships as key and unique constraints etc
923 writer.WriteEndElement();
927 writer.WriteEndElement();
930 private void WriteTableSchema( XmlWriter writer, DataTable table )
936 SplitColumns( table,out atts, out elements, out simple );
938 //<xs:element name="TableName">
939 writer.WriteStartElement( XmlConstants.SchemaPrefix,
940 XmlConstants.Element,
941 XmlConstants.SchemaNamespace );
943 writer.WriteAttributeString( XmlConstants.Name, table.TableName );
946 writer.WriteStartElement( XmlConstants.SchemaPrefix,
947 XmlConstants.ComplexType,
948 XmlConstants.SchemaNamespace );
950 //TODO - what about the simple content?
951 if( elements.Count == 0 )
956 //A sequence of element types or a simple content node
958 writer.WriteStartElement( XmlConstants.SchemaPrefix,
959 XmlConstants.Sequence,
960 XmlConstants.SchemaNamespace );
961 foreach( DataColumn col in elements )
963 //<xs:element name=ColumnName type=MappedType Ordinal=index>
964 writer.WriteStartElement( XmlConstants.SchemaPrefix,
965 XmlConstants.Element,
966 XmlConstants.SchemaNamespace );
968 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
970 if (col.ColumnName != col.Caption && col.Caption != string.Empty)
971 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Caption,
972 XmlConstants.MsdataNamespace, col.Caption);
974 if (col.DefaultValue.ToString () != string.Empty)
975 writer.WriteAttributeString( XmlConstants.Default, col.DefaultValue.ToString ());
977 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
979 if( col.AllowDBNull )
981 writer.WriteAttributeString( XmlConstants.MinOccurs, "0" );
984 //writer.WriteAttributeString( XmlConstants.MsdataPrefix,
985 // XmlConstants.Ordinal,
986 // XmlConstants.MsdataNamespace,
987 // col.Ordinal.ToString() );
989 // Write SimpleType if column have MaxLength
990 if (col.MaxLength > -1) {
992 WriteTableSimpleType (writer, col);
997 writer.WriteEndElement();
1000 writer.WriteEndElement();
1003 //Then a list of attributes
1004 foreach( DataColumn col in atts )
1006 //<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
1007 writer.WriteStartElement( XmlConstants.SchemaPrefix,
1008 XmlConstants.Attribute,
1009 XmlConstants.SchemaNamespace );
1011 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
1012 writer.WriteAttributeString( XmlConstants.Form, XmlConstants.Unqualified );
1013 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
1015 writer.WriteEndElement();
1019 writer.WriteEndElement();
1022 writer.WriteEndElement();
1025 private void WriteTableSimpleType (XmlWriter writer, DataColumn col)
1028 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.SimpleType,
1029 XmlConstants.SchemaNamespace);
1032 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.Restriction,
1033 XmlConstants.SchemaNamespace);
1035 writer.WriteAttributeString( XmlConstants.Base, MapType( col.DataType ) );
1038 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.MaxLength,
1039 XmlConstants.SchemaNamespace);
1040 writer.WriteAttributeString( XmlConstants.Value, col.MaxLength.ToString ());
1043 writer.WriteEndElement();
1045 writer.WriteEndElement();
1047 writer.WriteEndElement();
1051 /// Helper function to split columns into attributes elements and simple
1054 private void SplitColumns( DataTable table,
1056 out ArrayList elements,
1057 out DataColumn simple)
1059 //The columns can be attributes, hidden, elements, or simple content
1060 //There can be 0-1 simple content cols or 0-* elements
1061 atts = new System.Collections.ArrayList();
1062 elements = new System.Collections.ArrayList();
1065 //Sort out the columns
1066 foreach( DataColumn col in table.Columns )
1068 switch( col.ColumnMapping )
1070 case MappingType.Attribute:
1073 case MappingType.Element:
1074 elements.Add( col );
1076 case MappingType.SimpleContent:
1077 if( simple != null )
1079 throw new System.InvalidOperationException( "There may only be one simple content element" );
1084 //ignore Hidden elements
1091 private string MapType( Type type )
1093 string Result = "xs:string";
1095 // TODO: More types to map?
1097 if (typeof (string) == type)
1098 Result = "xs:string";
1099 else if (typeof (short) == type)
1100 Result = "xs:short";
1101 else if (typeof (int) == type)
1103 else if (typeof (long) == type)
1105 else if (typeof (bool) == type)
1106 Result = "xs:boolean";
1107 else if (typeof (byte) == type)
1108 Result = "xs:unsignedByte";
1109 else if (typeof (char) == type)
1111 else if (typeof (DateTime) == type)
1112 Result = "xs:dateTime";
1113 else if (typeof (decimal) == type)
1114 Result = "xs:decimal";
1115 else if (typeof (double) == type)
1116 Result = "xs:double";
1117 else if (typeof (sbyte) == type)
1118 Result = "xs:sbyte";
1119 else if (typeof (Single) == type)
1120 Result = "xs:float";
1121 else if (typeof (TimeSpan) == type)
1122 Result = "xs:duration";
1123 else if (typeof (ushort) == type)
1124 Result = "xs:usignedShort";
1125 else if (typeof (uint) == type)
1126 Result = "xs:unsignedInt";
1127 else if (typeof (ulong) == type)
1128 Result = "xs:unsignedLong";
1133 #endregion //Private Xml Serialisation