-using System;\r
+\r
+//\r
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
using System.IO;\r
using System.Data;\r
using System.Xml;\r
\r
private void Process ()\r
{\r
- // set EnforceConstraint to false during load time.\r
bool savedEnforceConstraints =\r
dataset.EnforceConstraints;\r
+ try {\r
dataset.EnforceConstraints = false;\r
-\r
reader.MoveToContent ();\r
\r
if (mode == XmlReadMode.Fragment) {\r
- do {\r
- if (XmlConvert.DecodeName (reader.LocalName) == dataset.DataSetName && reader.NamespaceURI == dataset.Namespace)\r
+ while (reader.NodeType == XmlNodeType.Element && !reader.EOF) {\r
ReadTopLevelElement ();\r
- else\r
- reader.Skip ();\r
- } while (!reader.EOF);\r
- } else {\r
- // Top level element can be ignored, being regarded \r
- // just as a wrapper (even it is not dataset element).\r
- DataTable tab = dataset.Tables [XmlConvert.DecodeName (reader.LocalName)];\r
- if (tab != null && tab.Namespace == reader.NamespaceURI)\r
- ReadDataSetContent ();\r
+ }\r
+ }\r
else\r
ReadTopLevelElement ();\r
- reader.MoveToContent ();\r
+ } finally {\r
+ dataset.EnforceConstraints = \r
+ savedEnforceConstraints;\r
}\r
+ }\r
+\r
+ private bool IsTopLevelDataSet ()\r
+ {\r
+ string local = XmlConvert.DecodeName (reader.LocalName);\r
\r
- dataset.EnforceConstraints = savedEnforceConstraints;\r
+ // No need to check DataSetName. In fact, it is ignored.\r
+\r
+ bool ambiguous = false;\r
+ DataTable dt = dataset.Tables [local];\r
+ if (dt == null)\r
+ return true;\r
+\r
+ XmlDocument doc = new XmlDocument ();\r
+ XmlElement el = (XmlElement) doc.ReadNode (reader);\r
+ doc.AppendChild (el);\r
+ reader = new XmlNodeReader (el);\r
+ reader.MoveToContent ();\r
+\r
+ return !XmlDataInferenceLoader.IsDocumentElementTable (\r
+ el, null);\r
}\r
\r
private void ReadTopLevelElement ()\r
{\r
+ if (mode == XmlReadMode.Fragment &&\r
+ (XmlConvert.DecodeName (reader.LocalName) !=\r
+ dataset.DataSetName ||\r
+ reader.NamespaceURI != dataset.Namespace))\r
+ reader.Skip ();\r
+ else if (mode == XmlReadMode.Fragment ||\r
+ IsTopLevelDataSet ()) {\r
int depth = reader.Depth;\r
reader.Read ();\r
reader.MoveToContent ();\r
do {\r
ReadDataSetContent ();\r
} while (reader.Depth > depth && !reader.EOF);\r
-\r
- if (reader.IsEmptyElement)\r
- reader.Read ();\r
if (reader.NodeType == XmlNodeType.EndElement)\r
reader.ReadEndElement ();\r
reader.MoveToContent ();\r
}\r
+ else\r
+ ReadDataSetContent ();\r
+ }\r
\r
private void ReadDataSetContent ()\r
{\r
}\r
\r
// skip if namespace does not match.\r
- // TODO: This part is suspicious for MS compatibility\r
- // (test required)\r
if (table.Namespace != reader.NamespaceURI) {\r
reader.Skip ();\r
reader.MoveToContent ();\r
// Consume attributes\r
if (reader.MoveToFirstAttribute ()) {\r
do {\r
- if (reader.NamespaceURI == xmlnsNS)\r
+ if (reader.NamespaceURI == XmlConstants.XmlnsNS)\r
continue;\r
ReadElementAttribute (row);\r
} while (reader.MoveToNextAttribute ());\r
DataColumn col = row.Table.Columns [XmlConvert.DecodeName (reader.LocalName)];\r
if (col == null || col.Namespace != reader.NamespaceURI)\r
return;\r
- row [col] = reader.Value;\r
+ row [col] = StringToObject (col.DataType, reader.Value);\r
}\r
\r
private void ReadElementContent (DataRow row)\r
#if SILLY_MS_COMPATIBLE\r
// As to MS, "test string" and "test <!-- comment -->string" are different :P\r
if (simple != null && row.IsNull (simple))\r
- row [simple] = s;\r
+ row [simple] = StringToObject (simple.DataType, s);\r
#else\r
+// But it does not mean we support "123<!-- comment -->456". just allowed for string\r
if (simple != null)\r
row [simple] += s;\r
#endif\r
\r
bool wasEmpty = reader.IsEmptyElement;\r
int depth = reader.Depth;\r
- row [col] = reader.ReadElementString ();\r
+ row [col] = StringToObject (col.DataType, reader.ReadElementString ());\r
if (!wasEmpty && reader.Depth > depth) {\r
// This means, instance does not match with\r
// the schema (because the instance element\r
reader.Skip ();\r
reader.MoveToContent ();\r
}\r
+\r
+ internal static object StringToObject (Type type, string value)\r
+ {\r
+ if (type == null) return value;\r
+\r
+ switch (Type.GetTypeCode (type)) {\r
+ case TypeCode.Boolean: return XmlConvert.ToBoolean (value);\r
+ case TypeCode.Byte: return XmlConvert.ToByte (value);\r
+ case TypeCode.Char: return (char)XmlConvert.ToInt32 (value);\r
+ case TypeCode.DateTime: return XmlConvert.ToDateTime (value);\r
+ case TypeCode.Decimal: return XmlConvert.ToDecimal (value);\r
+ case TypeCode.Double: return XmlConvert.ToDouble (value);\r
+ case TypeCode.Int16: return XmlConvert.ToInt16 (value);\r
+ case TypeCode.Int32: return XmlConvert.ToInt32 (value);\r
+ case TypeCode.Int64: return XmlConvert.ToInt64 (value);\r
+ case TypeCode.SByte: return XmlConvert.ToSByte (value);\r
+ case TypeCode.Single: return XmlConvert.ToSingle (value);\r
+ case TypeCode.UInt16: return XmlConvert.ToUInt16 (value);\r
+ case TypeCode.UInt32: return XmlConvert.ToUInt32 (value);\r
+ case TypeCode.UInt64: return XmlConvert.ToUInt64 (value);\r
+ }\r
+\r
+ if (type == typeof (TimeSpan)) return XmlConvert.ToTimeSpan (value);\r
+ if (type == typeof (Guid)) return XmlConvert.ToGuid (value);\r
+ if (type == typeof (byte[])) return Convert.FromBase64String (value);\r
+\r
+ return Convert.ChangeType (value, type);\r
+ }\r
}\r
}\r