2 // mcs/class/System.Data/System.Data/XmlDataLoader.cs
4 // Purpose: Loads XmlDocument to DataSet
6 // class: XmlDataLoader
7 // assembly: System.Data.dll
8 // namespace: System.Data
11 // Ville Palo <vi64pa@koti.soon.fi>
13 // (c)copyright 2002 Ville Palo
15 // XmlDataLoader is included within the Mono Class Library.
21 using System.Xml.XPath;
22 using System.Collections;
23 using System.Globalization;
25 namespace System.Data {
27 internal class XmlDataLoader
31 Hashtable DiffGrRows = new Hashtable ();
33 public XmlDataLoader (DataSet set)
38 public XmlReadMode LoadData (XmlReader reader, XmlReadMode mode)
40 XmlReadMode Result = XmlReadMode.Auto;
44 case XmlReadMode.Fragment:
46 case XmlReadMode.ReadSchema:
47 Result = XmlReadMode.ReadSchema;
48 ReadModeSchema (reader, false);
50 case XmlReadMode.IgnoreSchema:
51 Result = XmlReadMode.IgnoreSchema;
52 ReadModeSchema (reader, true);
54 case XmlReadMode.InferSchema:
55 Result = XmlReadMode.InferSchema;
56 ReadModeInferSchema (reader);
67 // XmlReadMode.InferSchema
69 private void ReadModeInferSchema (XmlReader reader)
71 // root element is DataSets name
72 reader.MoveToContent ();
74 DSet.DataSetName = reader.LocalName;
76 // And now comes tables
77 while (reader.Read ()) {
79 // skip possible inline-schema
80 if (String.Compare (reader.LocalName, "schema", true) == 0 && reader.NodeType == XmlNodeType.Element) {
81 while (reader.Read () && (reader.NodeType != XmlNodeType.EndElement
82 || String.Compare (reader.LocalName, "schema", true) != 0));
86 if (reader.NodeType == XmlNodeType.Element) {
88 string datatablename = reader.LocalName;
90 bool NewTable = false;
92 if (!DSet.Tables.Contains (datatablename)) {
93 table = new DataTable (reader.LocalName);
94 DSet.Tables.Add (table);
98 table = DSet.Tables [datatablename];
101 Hashtable rowValue = new Hashtable ();
103 while (reader.Read () && (reader.NodeType != XmlNodeType.EndElement
104 || reader.LocalName != datatablename))
106 if (reader.NodeType == XmlNodeType.Element) {
108 string dataColumnName = reader.LocalName;
110 table.Columns.Add (dataColumnName);
116 rowValue.Add (dataColumnName, reader.Value);
120 DataRow row = table.NewRow ();
122 IDictionaryEnumerator enumerator = rowValue.GetEnumerator ();
123 while (enumerator.MoveNext ()) {
124 row [enumerator.Key.ToString ()] = enumerator.Value.ToString ();
127 table.Rows.Add (row);
132 // Read Xmldocument. XmlReadMode.ReadSchema and XmlReadMode.IgnoreSchema
134 private void ReadModeSchema (XmlReader reader, bool IgnoreSchema)
137 * Reads any inline schema, but an exception is thrown
138 * if any tables in the inline schema already exist in the DataSet.
141 reader.MoveToContent ();
142 reader.ReadStartElement ();
143 reader.MoveToContent ();
145 while (reader.NodeType != XmlNodeType.EndElement)
147 if (reader.NodeType == XmlNodeType.Element)
149 // FIXME: possible inline-schema should be readed here
150 if (String.Compare (reader.LocalName, "schema", true) == 0)
\r
153 DSet.ReadXmlSchema (reader);
157 if (DSet.Tables.Contains (reader.LocalName))
\r
159 DataTable table = DSet.Tables [reader.LocalName];
160 DataRow row = table.NewRow ();
162 reader.ReadStartElement ();
163 ReadColumns (reader, row, table, reader.LocalName);
164 reader.ReadEndElement ();
166 table.Rows.Add (row);
169 reader.MoveToContent ();
173 #endregion // reading
175 #region Private helper methods
177 private void ReadColumns (XmlReader reader, DataRow row, DataTable table, string TableName)
180 if (reader.NodeType == XmlNodeType.Element) {
181 DataColumn col = table.Columns [reader.LocalName];
184 row [col] = StringToObject (col.DataType, reader.Value);
191 } while (table.TableName != reader.LocalName
192 || reader.NodeType != XmlNodeType.EndElement);
195 internal static object StringToObject (Type type, string value)
197 if (type == null) return value;
199 switch (Type.GetTypeCode (type))
201 case TypeCode.Boolean: return XmlConvert.ToBoolean (value);
202 case TypeCode.Byte: return XmlConvert.ToByte (value);
203 case TypeCode.Char: return (char)XmlConvert.ToInt32 (value);
204 case TypeCode.DateTime: return XmlConvert.ToDateTime (value);
205 case TypeCode.Decimal: return XmlConvert.ToDecimal (value);
206 case TypeCode.Double: return XmlConvert.ToDouble (value);
207 case TypeCode.Int16: return XmlConvert.ToInt16 (value);
208 case TypeCode.Int32: return XmlConvert.ToInt32 (value);
209 case TypeCode.Int64: return XmlConvert.ToInt64 (value);
210 case TypeCode.SByte: return XmlConvert.ToSByte (value);
211 case TypeCode.Single: return XmlConvert.ToSingle (value);
212 case TypeCode.UInt16: return XmlConvert.ToUInt16 (value);
213 case TypeCode.UInt32: return XmlConvert.ToUInt32 (value);
214 case TypeCode.UInt64: return XmlConvert.ToUInt64 (value);
217 if (type == typeof (TimeSpan)) return XmlConvert.ToTimeSpan (value);
\r
218 if (type == typeof (byte[])) return Convert.FromBase64String (value);
\r
220 return Convert.ChangeType (value, type);
223 #endregion // Private helper methods