// Stuart Caborn <stuart.caborn@virgin.net>
// Tim Coleman (tim@timcoleman.com)
// Ville Palo <vi64pa@koti.soon.fi>
+// Atsushi Enomoto <atsushi@ximian.com>
//
// (C) Ximian, Inc. 2002
// Copyright (C) Tim Coleman, 2002, 2003
//
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
using System;
using System.Collections;
using System.ComponentModel;
[ToolboxItem (false)]
[DefaultProperty ("DataSetName")]
+ [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.DataSetDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
+
[Serializable]
public class DataSet : MarshalByValueComponent, IListSource,
ISupportInitialize, ISerializable, IXmlSerializable
private PropertyCollection properties;
private DataViewManager defaultView;
private CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
+ internal XmlDataDocument _xmlDataDocument = null;
#region Constructors
this.Locale = CultureInfo.CurrentCulture;
}
- [MonoTODO]
protected DataSet (SerializationInfo info, StreamingContext context) : this ()
{
- throw new NotImplementedException ();
+ GetSerializationData (info, context);
}
#endregion // Constructors
return caseSensitive;
}
set {
- foreach (DataTable T in Tables) {
- if (T.VirginCaseSensitive)
- T.CaseSensitive = value;
- }
-
caseSensitive = value;
if (!caseSensitive) {
foreach (DataTable table in Tables) {
[DataSysDescription ("Indicates the XML uri namespace for the root element pointed at by this DataSet.")]
[DefaultValue ("")]
public string Namespace {
- [MonoTODO]
get { return _namespace; }
- [MonoTODO]
set {
//TODO - trigger an event if this happens?
- _namespace = value;
+ if (value == null)
+ value = String.Empty;
+ if (value != this._namespace)
+ RaisePropertyChanging ("Namespace");
+ _namespace = value;
}
}
[DataSysDescription ("Indicates the prefix of the namespace used for this DataSet.")]
[DefaultValue ("")]
public string Prefix {
- [MonoTODO]
get { return prefix; }
- [MonoTODO]
set {
- //TODO - trigger an event if this happens?
+ if (value == null)
+ value = String.Empty;
+ // Prefix cannot contain any special characters other than '_' and ':'
+ for (int i = 0; i < value.Length; i++) {
+ if (!(Char.IsLetterOrDigit (value [i])) && (value [i] != '_') && (value [i] != ':'))
+ throw new DataException ("Prefix '" + value + "' is not valid, because it contains special characters.");
+ }
+
if (value == null)
value = string.Empty;
tempTable.AcceptChanges ();
}
+ /// <summary>
+ /// Clears all the tables
+ /// </summary>
public void Clear ()
{
- // TODO: if currently bound to a XmlDataDocument
- // throw a NotSupportedException
- for (int t = 0; t < tableCollection.Count; t++) {
+ if (_xmlDataDocument != null)
+ throw new NotSupportedException ("Clear function on dataset and datatable is not supported when XmlDataDocument is bound to the DataSet.");
+ bool enforceConstraints = this.EnforceConstraints;
+ this.EnforceConstraints = false;
+ for (int t = 0; t < tableCollection.Count; t++) {
tableCollection[t].Clear ();
}
+ this.EnforceConstraints = enforceConstraints;
}
public virtual DataSet Clone ()
{
- DataSet Copy = new DataSet ();
+ // need to return the same type as this...
+ DataSet Copy = (DataSet) Activator.CreateInstance(GetType(), true);
+
CopyProperties (Copy);
foreach (DataTable Table in Tables) {
- Copy.Tables.Add (Table.Clone ());
+ // tables are often added in no-args constructor, don't add them
+ // twice.
+ if (!Copy.Tables.Contains(Table.TableName)) {
+ Copy.Tables.Add (Table.Clone ());
+ }
}
//Copy Relationships between tables after existance of tables
return Copy;
}
- [MonoTODO]
private void CopyProperties (DataSet Copy)
{
Copy.CaseSensitive = CaseSensitive;
//Copy.DefaultViewManager
//Copy.DesignMode
Copy.EnforceConstraints = EnforceConstraints;
- //Copy.ExtendedProperties
- //Copy.HasErrors
- //Copy.Locale = Locale;
+ if(ExtendedProperties.Count > 0) {
+ // Cannot copy extended properties directly as the property does not have a set accessor
+ Array tgtArray = Array.CreateInstance( typeof (object), ExtendedProperties.Count);
+ ExtendedProperties.Keys.CopyTo (tgtArray, 0);
+ for (int i=0; i < ExtendedProperties.Count; i++)
+ Copy.ExtendedProperties.Add (tgtArray.GetValue (i), ExtendedProperties[tgtArray.GetValue (i)]);
+ }
+ Copy.Locale = Locale;
Copy.Namespace = Namespace;
Copy.Prefix = Prefix;
- //Copy.Site = Site;
+ //Copy.Site = Site; // FIXME : Not sure of this.
}
}
DataRow newRow = copyTable.NewRow ();
- copyTable.Rows.Add (newRow);
row.CopyValuesToRow (newRow);
+ copyTable.Rows.Add (newRow);
newRow.XmlRowID = row.XmlRowID;
addedRows.Add (row,row);
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public DataTableReader GetDataReader (DataTable[] dataTables)
{
public string GetXml ()
{
StringWriter Writer = new StringWriter ();
-
- // Sending false for not printing the Processing instruction
- WriteXml (Writer, XmlWriteMode.IgnoreSchema, false);
+ WriteXml (Writer, XmlWriteMode.IgnoreSchema);
return Writer.ToString ();
}
return false;
}
- [MonoTODO]
public void InferXmlSchema (XmlReader reader, string[] nsArray)
{
+ if (reader == null)
+ return;
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (reader);
+ InferXmlSchema (doc, nsArray);
+ }
+
+ private void InferXmlSchema (XmlDocument doc, string [] nsArray)
+ {
+ XmlDataInferenceLoader.Infer (this, doc, XmlReadMode.InferSchema, nsArray);
}
public void InferXmlSchema (Stream stream, string[] nsArray)
}
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public void Load (IDataReader reader, LoadOption loadOption, DataTable[] tables)
{
{
XmlTextWriter writer = new XmlTextWriter (fileName, null);
writer.Formatting = Formatting.Indented;
- WriteXml (writer);
-
- writer.Close ();
+ writer.WriteStartDocument (true);
+ try {
+ WriteXml (writer);
+ }
+ finally {
+ writer.WriteEndDocument ();
+ writer.Close ();
+ }
}
public void WriteXml (TextWriter writer)
public void WriteXml (XmlWriter writer)
{
- WriteXml (writer, XmlWriteMode.IgnoreSchema, true);
+ WriteXml (writer, XmlWriteMode.IgnoreSchema);
}
public void WriteXml (string filename, XmlWriteMode mode)
{
XmlTextWriter writer = new XmlTextWriter (filename, null);
writer.Formatting = Formatting.Indented;
- WriteXml (writer, mode, true);
+ writer.WriteStartDocument (true);
+
+ try {
+ WriteXml (writer, mode);
+ }
+ finally {
+ writer.WriteEndDocument ();
+ writer.Close ();
+ }
}
public void WriteXml (Stream stream, XmlWriteMode mode)
{
XmlTextWriter writer = new XmlTextWriter (stream, null);
writer.Formatting = Formatting.Indented;
- WriteXml (writer, mode, true);
+ WriteXml (writer, mode);
}
public void WriteXml (TextWriter writer, XmlWriteMode mode)
{
XmlTextWriter xwriter = new XmlTextWriter (writer);
xwriter.Formatting = Formatting.Indented;
- WriteXml (xwriter, mode, true);
+ WriteXml (xwriter, mode);
}
public void WriteXml (XmlWriter writer, XmlWriteMode mode)
{
- WriteXml (writer, mode, true);
- }
-
- internal void WriteXml (Stream stream, XmlWriteMode mode, bool writePI)
- {
- XmlTextWriter writer = new XmlTextWriter (stream, null);
- writer.Formatting = Formatting.Indented;
- WriteXml (writer, mode, writePI);
- }
-
- internal void WriteXml (string fileName, XmlWriteMode mode, bool writePI)
- {
- XmlTextWriter writer = new XmlTextWriter (fileName, null);
- writer.Formatting = Formatting.Indented;
- WriteXml (writer, mode, writePI);
-
- writer.Close ();
- }
-
- internal void WriteXml (TextWriter writer, XmlWriteMode mode, bool writePI)
- {
- XmlTextWriter xwriter = new XmlTextWriter (writer);
- xwriter.Formatting = Formatting.Indented;
- WriteXml (xwriter, mode, writePI);
- }
-
- internal void WriteXml (XmlWriter writer, XmlWriteMode mode, bool writePI)
- {
- if (writePI && (writer.WriteState == WriteState.Start))
- writer.WriteStartDocument (true);
-
if (mode == XmlWriteMode.DiffGram) {
SetRowsID();
WriteDiffGramElement(writer);
}
- WriteStartElement (writer, mode, Namespace, Prefix, XmlConvert.EncodeName (DataSetName));
-
- /*********************************************************
- * This is a patch for interoperability with ms.net. *
- * Because in web services the .net client expects this *
- * atrribute even if namespace is an empty string *
- ********************************************************/
- if (Namespace == null || Namespace.Length == 0)
- WriteAttributeString (writer, mode, null, null, "xmlns", Namespace);
-
-
- if (mode == XmlWriteMode.WriteSchema) {
- DoWriteXmlSchema (writer);
+ // It should not write when there is no content to be written
+ bool shouldOutputContent = (mode != XmlWriteMode.DiffGram);
+ for (int n = 0; n < tableCollection.Count && !shouldOutputContent; n++)
+ shouldOutputContent = tableCollection [n].Rows.Count > 0;
+
+ if (shouldOutputContent) {
+ WriteStartElement (writer, mode, Namespace, Prefix, XmlConvert.EncodeName (DataSetName));
+
+ if (mode == XmlWriteMode.WriteSchema)
+ DoWriteXmlSchema (writer);
+
+ WriteTables (writer, mode, Tables, DataRowVersion.Default);
+ writer.WriteEndElement ();
}
- WriteTables (writer, mode, Tables, DataRowVersion.Default);
if (mode == XmlWriteMode.DiffGram) {
- writer.WriteEndElement (); //DataSet name
if (HasChanges(DataRowState.Modified | DataRowState.Deleted)) {
- DataSet beforeDS = GetChanges (DataRowState.Modified | DataRowState.Deleted);
+ DataSet beforeDS = GetChanges (DataRowState.Modified | DataRowState.Deleted);
WriteStartElement (writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "before");
WriteTables (writer, mode, beforeDS.Tables, DataRowVersion.Original);
writer.WriteEndElement ();
}
}
- writer.WriteEndElement (); // DataSet name or diffgr:diffgram
+
+ if (mode == XmlWriteMode.DiffGram)
+ writer.WriteEndElement (); // diffgr:diffgram
+
+ writer.Flush ();
}
public void WriteXmlSchema (Stream stream)
public void WriteXmlSchema (string fileName)
{
XmlTextWriter writer = new XmlTextWriter (fileName, null);
- writer.Formatting = Formatting.Indented;
- WriteXmlSchema (writer);
+ try {
+ writer.Formatting = Formatting.Indented;
+ writer.WriteStartDocument (true);
+ WriteXmlSchema (writer);
+ } finally {
+ writer.WriteEndDocument ();
+ writer.Close ();
+ }
}
public void WriteXmlSchema (TextWriter writer)
{
XmlTextWriter xwriter = new XmlTextWriter (writer);
- xwriter.Formatting = Formatting.Indented;
- WriteXmlSchema (xwriter);
+ try {
+ xwriter.Formatting = Formatting.Indented;
+// xwriter.WriteStartDocument ();
+ WriteXmlSchema (xwriter);
+ } finally {
+// xwriter.WriteEndDocument ();
+ xwriter.Close ();
+ }
}
public void WriteXmlSchema (XmlWriter writer)
{
//Create a skeleton doc and then write the schema
//proper which is common to the WriteXml method in schema mode
- writer.WriteStartDocument ();
DoWriteXmlSchema (writer);
-
- writer.WriteEndDocument ();
}
public void ReadXmlSchema (Stream stream)
public void ReadXmlSchema (string str)
{
XmlReader reader = new XmlTextReader (str);
- ReadXmlSchema (reader);
+ try {
+ ReadXmlSchema (reader);
+ }
+ finally {
+ reader.Close ();
+ }
}
public void ReadXmlSchema (TextReader treader)
public void ReadXmlSchema (XmlReader reader)
{
+#if true
+ new XmlSchemaDataImporter (this, reader).Process ();
+#else
XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
SchemaMapper.Read (reader);
+#endif
}
public XmlReadMode ReadXml (Stream stream)
public XmlReadMode ReadXml (string str)
{
- return ReadXml (new XmlTextReader (str));
+ XmlTextReader reader = new XmlTextReader (str);
+ try {
+ return ReadXml (reader);
+ }
+ finally {
+ reader.Close ();
+ }
}
public XmlReadMode ReadXml (TextReader reader)
public XmlReadMode ReadXml (XmlReader r)
{
- XmlDataLoader Loader = new XmlDataLoader (this);
- // FIXME: somekinda exception?
- if (!r.Read ())
- return XmlReadMode.Auto; // FIXME
-
- // Check if the curent element is the process instruction (PI).
- // if it is move to next element.
- if (r.LocalName == "xml")
- r.MoveToContent();
-
- // The document can be diffgram if :
- // 1. The first element is diffgram.
- if (r.LocalName == "diffgram") {
- return ReadXml (r, XmlReadMode.DiffGram);
- }
-
- bool schemaRead = false;
- if (r.LocalName == "schema") {
- ReadXmlSchema (r);
- r.MoveToContent();
- schemaRead = true;
- }
-
- // If we read the schema the next element can be a diffgram
- // that is what happen in web services soap message.
- if (schemaRead && r.LocalName == "diffgram") {
- return ReadXml (r, XmlReadMode.DiffGram);
- }
-
- // Get the DataSet name.
- // if this xml is not diffgram then the first element will be the
- // DataSet name.
- string dataSetName = XmlConvert.DecodeName (r.LocalName);
- DataSetName = dataSetName;
-
- r.ReadStartElement ();
- r.MoveToContent();
-
-
- // After reading the dataset name there can be three scenarios:
- // 1. The next part will be the schema of the dataset.
- // 2. The next part will be the data of the dataset using diffgram.
- // 3. The next part will be the data of tha dataset without diffgram.
- // Check if the current element is the schema
- if (r.LocalName == "schema") {
- ReadXmlSchema (r);
- r.MoveToContent();
- schemaRead = true;
- }
-
- // check if the data was written in a diffgram mode.
- if (r.LocalName == "diffgram") {
- return ReadXml (r, XmlReadMode.DiffGram);
- }
-
- // If the schema has been read we should read the rest data of the dataset
- // with ignoreschema mode.
- if (schemaRead) {
- ReadXml (r, XmlReadMode.IgnoreSchema, false);
- return XmlReadMode.ReadSchema;
- }
-
- // Read the data of the dataset with inferschema.
- return ReadXml (r, XmlReadMode.InferSchema, false);
-
+ return ReadXml (r, XmlReadMode.Auto);
}
public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
public XmlReadMode ReadXml (string str, XmlReadMode mode)
{
- return ReadXml (new XmlTextReader (str), mode);
+ XmlTextReader reader = new XmlTextReader (str);
+ try {
+ return ReadXml (reader, mode);
+ }
+ finally {
+ reader.Close ();
+ }
}
public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
return ReadXml (new XmlTextReader (reader), mode);
}
- [MonoTODO]
- public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
+ // LAMESPEC: XmlReadMode.Fragment is far from presisely
+ // documented. MS.NET infers schema against this mode.
+ public XmlReadMode ReadXml (XmlReader input, XmlReadMode mode)
{
- // we have to initiate the reader.
- if (reader.ReadState == ReadState.Initial)
- reader.Read();
-
- // Check if the curent element is the process instruction (PI).
- // if it is move to next element.
- if (reader.LocalName == "xml")
- reader.MoveToContent();
+ switch (input.ReadState) {
+ case ReadState.EndOfFile:
+ case ReadState.Error:
+ case ReadState.Closed:
+ return mode;
+ }
+ // Skip XML declaration and prolog
+ input.MoveToContent ();
+ if (input.EOF)
+ return mode;
+
+ // FIXME: We need more decent code here, but for now
+ // I don't know the precise MS.NET behavior, I just
+ // delegate to specific read process.
+ switch (mode) {
+ case XmlReadMode.IgnoreSchema:
+ return ReadXmlIgnoreSchema (input, mode, true);
+ case XmlReadMode.ReadSchema:
+ return ReadXmlReadSchema (input, mode, true);
+ }
+ // remaining modes are: Auto, InferSchema, Fragment, Diffgram
+
+ XmlReader reader = input;
+
+ int depth = reader.Depth;
+ XmlReadMode result = mode;
+ bool skippedTopLevelElement = false;
+ string potentialDataSetName = null;
+ XmlDocument doc = null;
+ bool shouldReadData = mode != XmlReadMode.DiffGram;
+ bool shouldNotInfer = Tables.Count > 0;
+
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ doc = new XmlDocument ();
+ do {
+ doc.AppendChild (doc.ReadNode (reader));
+ } while (!reader.EOF &&
+ doc.DocumentElement == null);
+ reader = new XmlNodeReader (doc);
+ reader.MoveToContent ();
+ break;
+ case XmlReadMode.DiffGram:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace))
+ goto case XmlReadMode.Auto;
+ break;
+ }
- XmlReadMode Result = XmlReadMode.Auto;
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ case XmlReadMode.ReadSchema:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace) &&
+ !(reader.LocalName == "schema" &&
+ reader.NamespaceURI == XmlSchema.Namespace))
+ potentialDataSetName = reader.LocalName;
+ goto default;
+ case XmlReadMode.Fragment:
+ break;
+ default:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace) &&
+ !(reader.LocalName == "schema" &&
+ reader.NamespaceURI == XmlSchema.Namespace)) {
+ if (!reader.IsEmptyElement) {
+ reader.Read ();
+ reader.MoveToContent ();
+ skippedTopLevelElement = true;
+ }
+ else {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ DataSetName = reader.LocalName;
+ break;
+ }
+ reader.Read ();
+ }
+ }
+ break;
+ }
- if (mode == XmlReadMode.DiffGram) {
- if (reader.LocalName != "diffgram"){
- reader.MoveToContent ();
- reader.ReadStartElement (); // <DataSet>
+ // If schema, then read the first element as schema
+ if (reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) {
+ shouldNotInfer = true;
+ switch (mode) {
+ case XmlReadMode.IgnoreSchema:
+ case XmlReadMode.InferSchema:
+ reader.Skip ();
+ break;
+ case XmlReadMode.Fragment:
+ ReadXmlSchema (reader);
+ break;
+ case XmlReadMode.DiffGram:
+ case XmlReadMode.Auto:
+ if (Tables.Count == 0) {
+ ReadXmlSchema (reader);
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.ReadSchema;
+ } else {
+ // otherwise just ignore and return IgnoreSchema
+ reader.Skip ();
+ result = XmlReadMode.IgnoreSchema;
+ }
+ break;
+ case XmlReadMode.ReadSchema:
+ ReadXmlSchema (reader);
+ break;
+ }
+ }
+
+ // If diffgram, then read the first element as diffgram
+ if (reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.IgnoreSchema:
+ case XmlReadMode.DiffGram:
+ XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
+ DiffLoader.Load (reader);
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.DiffGram;
+ shouldReadData = false;
+ break;
+ case XmlReadMode.Fragment:
+ reader.Skip ();
+ break;
+ default:
+ reader.Skip ();
+ break;
+ }
+ }
- reader.MoveToContent ();
- if (reader.LocalName == "schema")
+ // if schema after diffgram, just skip it.
+ if (!shouldReadData && reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) {
+ shouldNotInfer = true;
+ switch (mode) {
+ default:
+ reader.Skip ();
+ break;
+ case XmlReadMode.ReadSchema:
+ case XmlReadMode.DiffGram:
+ if (Tables.Count == 0)
ReadXmlSchema (reader);
+ break;
+ }
+ }
- reader.MoveToContent ();
+ if (reader.EOF)
+ return result == XmlReadMode.Auto ?
+ potentialDataSetName != null && !shouldNotInfer ?
+ XmlReadMode.InferSchema :
+ XmlReadMode.IgnoreSchema : result;
+
+ // Otherwise, read as dataset... but only when required.
+ if (shouldReadData && !shouldNotInfer) {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ if (Tables.Count > 0)
+ goto case XmlReadMode.IgnoreSchema;
+ else
+ goto case XmlReadMode.InferSchema;
+ case XmlReadMode.InferSchema:
+ InferXmlSchema (doc, null);
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.InferSchema;
+ break;
+ case XmlReadMode.IgnoreSchema:
+ case XmlReadMode.Fragment:
+ case XmlReadMode.DiffGram:
+ break;
+ default:
+ shouldReadData = false;
+ break;
}
- XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
- DiffLoader.Load (reader);
- Result = XmlReadMode.DiffGram;
}
- else
- Result = ReadXml(reader, mode, true);
- return Result;
- }
+ if (shouldReadData) {
+ XmlReader dataReader = reader;
+ if (doc != null) {
+ dataReader = new XmlNodeReader (doc);
+ dataReader.MoveToContent ();
+ }
+ if (reader.NodeType == XmlNodeType.Element)
+ XmlDataReader.ReadXml (this, dataReader,
+ mode);
+ }
- private XmlReadMode ReadXml (XmlReader r, XmlReadMode mode, bool readDataSet) {
-
- if (readDataSet) {
- string dataSetName = XmlConvert.DecodeName (r.LocalName);
- DataSetName = dataSetName;
- // get the Namespace of the DataSet.
- string tmp = r.GetAttribute("xmlns");
- if (tmp != null)
- Namespace = tmp;
-
- r.ReadStartElement ();
- r.MoveToContent();
+ if (skippedTopLevelElement) {
+ switch (result) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+// DataSetName = potentialDataSetName;
+// result = XmlReadMode.InferSchema;
+ break;
+ }
+ if (reader.NodeType == XmlNodeType.EndElement)
+ reader.ReadEndElement ();
}
+//*
+ while (input.Depth > depth)
+ input.Read ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.Read ();
+//*/
+ input.MoveToContent ();
- XmlDataLoader Loader = new XmlDataLoader (this);
- return Loader.LoadData (r, mode);
+ return result == XmlReadMode.Auto ?
+ XmlReadMode.IgnoreSchema : result;
}
-
#endregion // Public Methods
#region Public Events
#endregion // Public Events
- #region Destructors
-
- ~DataSet ()
- {
- }
-
- #endregion Destructors
-
#region IListSource methods
IList IListSource.GetList ()
{
#region ISerializable
void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
{
- throw new NotImplementedException ();
+ StringWriter sw = new StringWriter ();
+ XmlTextWriter writer = new XmlTextWriter (sw);
+ DoWriteXmlSchema (writer);
+ writer.Flush ();
+ si.AddValue ("XmlSchema", sw.ToString ());
+
+ sw = new StringWriter ();
+ writer = new XmlTextWriter (sw);
+ WriteXml (writer, XmlWriteMode.DiffGram);
+ writer.Flush ();
+ si.AddValue ("XmlDiffGram", sw.ToString ());
}
#endregion
#region Protected Methods
protected void GetSerializationData (SerializationInfo info, StreamingContext context)
{
- string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
- if (s != null) ReadXmlSerializable (new XmlTextReader (new StringReader (s)));
+ string s = info.GetValue ("XmlSchema", typeof (String)) as String;
+ XmlTextReader reader = new XmlTextReader (new StringReader (s));
+ ReadXmlSchema (reader);
+ reader.Close ();
+
+ s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
+ reader = new XmlTextReader (new StringReader (s));
+ ReadXml (reader, XmlReadMode.DiffGram);
+ reader.Close ();
}
protected virtual void ReadXmlSerializable (XmlReader reader)
{
- ReadXml (reader, XmlReadMode.DiffGram); // FIXME
+ ReadXml (reader);
}
void IXmlSerializable.ReadXml (XmlReader reader)
{
-
ReadXmlSerializable(reader);
-
- // the XmlSerializationReader does this lines!!!
- //reader.MoveToContent ();
- //reader.ReadEndElement (); // </DataSet>
}
void IXmlSerializable.WriteXml (XmlWriter writer)
{
DoWriteXmlSchema (writer);
- WriteXml (writer, XmlWriteMode.DiffGram, true);
+ WriteXml (writer, XmlWriteMode.DiffGram);
+ }
+
+ XmlSchema IXmlSerializable.GetSchema ()
+ {
+ return GetSchemaSerializable ();
}
protected virtual bool ShouldSerializeRelations ()
{
}
- protected internal virtual void OnMergeFailed (MergeFailedEventArgs e)
+ internal virtual void OnMergeFailed (MergeFailedEventArgs e)
{
if (MergeFailed != null)
MergeFailed (this, e);
}
#endregion
- #region Private Xml Serialisation
+ #region Private Methods
+
+ private XmlReadMode ReadXmlIgnoreSchema (XmlReader input, XmlReadMode mode, bool checkRecurse)
+ {
+ if (input.LocalName == "schema" &&
+ input.NamespaceURI == XmlSchema.Namespace) {
+ input.Skip ();
+ }
+ else if (input.LocalName == "diffgram" &&
+ input.NamespaceURI == XmlConstants.DiffgrNamespace) {
+ XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
+ DiffLoader.Load (input);
+ }
+ else if (checkRecurse ||
+ input.LocalName == DataSetName &&
+ input.NamespaceURI == Namespace) {
+ XmlDataReader.ReadXml (this, input, mode);
+ }
+ else if (checkRecurse && !input.IsEmptyElement) {
+ int depth = input.Depth;
+ input.Read ();
+ input.MoveToContent ();
+ ReadXmlIgnoreSchema (input, mode, false);
+ while (input.Depth > depth)
+ input.Skip ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.ReadEndElement ();
+ }
+ input.MoveToContent ();
+ return XmlReadMode.IgnoreSchema;
+ }
+
+ private XmlReadMode ReadXmlReadSchema (XmlReader input, XmlReadMode mode, bool checkRecurse)
+ {
+ if (input.LocalName == "schema" &&
+ input.NamespaceURI == XmlSchema.Namespace) {
+ ReadXmlSchema (input);
+ }
+ else if (checkRecurse && !input.IsEmptyElement) {
+ int depth = input.Depth;
+ input.Read ();
+ input.MoveToContent ();
+ ReadXmlReadSchema (input, mode, false);
+ while (input.Depth > depth)
+ input.Skip ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.ReadEndElement ();
+ }
+ else
+ input.Skip ();
+ input.MoveToContent ();
+ return XmlReadMode.ReadSchema;
+ }
private string WriteObjectXml (object o)
{
}
if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
if (o is Guid) return XmlConvert.ToString ((Guid) o);
+ if (o is byte[]) return Convert.ToBase64String ((byte[])o);
return o.ToString ();
}
//part of another table structure via a nested parent relationship
foreach (DataTable table in tableCollection) {
bool isTopLevel = true;
+ /*
foreach (DataRelation rel in table.ParentRelations) {
if (rel.Nested) {
isTopLevel = false;
break;
}
}
-
+ */
if (isTopLevel) {
WriteTable ( writer, table, mode, version);
}
{
DataRow[] rows = new DataRow [table.Rows.Count];
table.Rows.CopyTo (rows, 0);
- WriteTable (writer, rows, mode, version);
+ WriteTable (writer, rows, mode, version, true);
}
- private void WriteTable (XmlWriter writer, DataRow[] rows, XmlWriteMode mode, DataRowVersion version)
+ private void WriteTable (XmlWriter writer, DataRow[] rows, XmlWriteMode mode, DataRowVersion version, bool skipIfNested)
{
//The columns can be attributes, hidden, elements, or simple content
//There can be 0-1 simple content cols or 0-* elements
SplitColumns (table, out atts, out elements, out simple);
//sort out the namespacing
string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
+ int relationCount = table.ParentRelations.Count;
+ DataRelation oneRel = relationCount == 1 ? table.ParentRelations [0] : null;
foreach (DataRow row in rows) {
+ if (skipIfNested) {
+ // Skip rows that is a child of any tables.
+ switch (relationCount) {
+ case 0:
+ break;
+ case 1:
+ if (!oneRel.Nested)
+ break;
+ if (row.GetParentRow (oneRel) != null)
+ continue;
+ break;
+ case 2:
+ bool skip = false;
+ for (int i = 0; i < table.ParentRelations.Count; i++) {
+ DataRelation prel = table.ParentRelations [i];
+ if (!prel.Nested)
+ continue;
+ if (row.GetParentRow (prel) != null) {
+ skip = true;
+ continue;
+ }
+ }
+ if (skip)
+ continue;
+ break;
+ }
+ }
+
if (!row.HasVersion(version) ||
(mode == XmlWriteMode.DiffGram && row.RowState == DataRowState.Unchanged
&& version == DataRowVersion.Original))
// If all of the columns were null, we have to write empty element
if (AllNulls) {
- writer.WriteElementString (table.TableName, "");
+ writer.WriteElementString (XmlConvert.EncodeLocalName (table.TableName), "");
continue;
}
}
else {
foreach (DataColumn col in elements) {
- WriteColumnAsElement (writer, mode, nspc, col, row, version);
+ WriteColumnAsElement (writer, mode, col, row, version);
}
}
foreach (DataRelation relation in table.ChildRelations) {
if (relation.Nested) {
- WriteTable (writer, row.GetChildRows (relation), mode, version);
+ WriteTable (writer, row.GetChildRows (relation), mode, version, false);
}
}
}
- private void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, string nspc, DataColumn col, DataRow row, DataRowVersion version)
+ private void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)
{
- string colnspc = nspc;
+ string colnspc = null;
object rowObject = row [col, version];
if (rowObject == null || rowObject == DBNull.Value)
return;
- if (col.Namespace != null) {
+ if (col.Namespace != String.Empty)
colnspc = col.Namespace;
- }
//TODO check if I can get away with write element string
- WriteStartElement (writer, mode, colnspc, col.Prefix, col.ColumnName);
+ WriteStartElement (writer, mode, colnspc, col.Prefix, XmlConvert.EncodeLocalName (col.ColumnName));
writer.WriteString (WriteObjectXml (rowObject));
writer.WriteEndElement ();
}
private void WriteColumnAsAttribute (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)
{
- WriteAttributeString (writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col, version].ToString ());
+ if (!row.IsNull (col))
+ WriteAttributeString (writer, mode, col.Namespace, col.Prefix, XmlConvert.EncodeLocalName (col.ColumnName), WriteObjectXml (row[col, version]));
}
private void WriteTableElement (XmlWriter writer, XmlWriteMode mode, DataTable table, DataRow row, DataRowVersion version)
//sort out the namespacing
string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
- WriteStartElement (writer, mode, nspc, table.Prefix, table.TableName);
+ WriteStartElement (writer, mode, nspc, table.Prefix, XmlConvert.EncodeLocalName (table.TableName));
if (mode == XmlWriteMode.DiffGram) {
WriteAttributeString (writer, mode, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "id", table.TableName + (row.XmlRowID + 1));
- WriteAttributeString (writer, mode, XmlConstants.MsdataNamespace, XmlConstants.MsdataPrefix, "rowOrder", row.XmlRowID.ToString());
+ WriteAttributeString (writer, mode, XmlConstants.MsdataNamespace, XmlConstants.MsdataPrefix, "rowOrder", XmlConvert.ToString (row.XmlRowID));
string modeName = null;
if (row.RowState == DataRowState.Modified)
modeName = "modified";
private void WriteStartElement (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name)
{
- if (nspc == null || nspc == "") {
- writer.WriteStartElement (name);
- }
- else if (prefix != null) {
- writer.WriteStartElement (prefix, name, nspc);
- }
- else {
- writer.WriteStartElement (writer.LookupPrefix (nspc), name, nspc);
- }
+ writer.WriteStartElement (prefix, name, nspc);
}
private void WriteAttributeString (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue)
}
writer.WriteEndElement (); // DataSet name or diffgr:diffgram
}
+
- XmlSchema IXmlSerializable.GetSchema ()
+ private void CheckNamespace (string prefix, string ns, XmlNamespaceManager nsmgr, XmlSchema schema)
{
- return BuildSchema ();
+ if (ns == String.Empty)
+ return;
+ if (ns != nsmgr.DefaultNamespace) {
+ if (nsmgr.LookupNamespace (nsmgr.NameTable.Get (prefix)) != ns) {
+ for (int i = 1; i < int.MaxValue; i++) {
+ string p = nsmgr.NameTable.Add ("app" + i);
+ if (!nsmgr.HasNamespace (p)) {
+ nsmgr.AddNamespace (p, ns);
+ HandleExternalNamespace (p, ns, schema);
+ break;
+ }
+ }
+ }
+ }
}
XmlSchema BuildSchema ()
{
string constraintPrefix = "";
XmlSchema schema = new XmlSchema ();
-
- schema.Namespaces.Add("xs", XmlSchema.Namespace);
- schema.Namespaces.Add(XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);
+ XmlNamespaceManager nsmgr = new XmlNamespaceManager (new NameTable ());
- if (Namespace != "" && Namespace != null) {
+ if (Namespace != "") {
schema.AttributeFormDefault = XmlSchemaForm.Qualified;
schema.ElementFormDefault = XmlSchemaForm.Qualified;
schema.TargetNamespace = Namespace;
- schema.Namespaces.Add(XmlConstants.TnsPrefix, Namespace);
constraintPrefix = XmlConstants.TnsPrefix + ":";
}
-
+
// set the schema id
schema.Id = DataSetName;
XmlDocument doc = new XmlDocument ();
- XmlAttribute xmlnsAttr = doc.CreateAttribute("xmlns");
- xmlnsAttr.Value = Namespace;
+ XmlAttribute attr = null;
+ ArrayList atts = new ArrayList ();
+
+ attr = doc.CreateAttribute ("", "xmlns", XmlConstants.XmlnsNS);
+ atts.Add (attr);
+
+ nsmgr.AddNamespace ("xs", XmlSchema.Namespace);
+ nsmgr.AddNamespace (XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);
+ if (Namespace != "") {
+ nsmgr.AddNamespace (XmlConstants.TnsPrefix, Namespace);
+ nsmgr.AddNamespace (String.Empty, Namespace);
+ }
+ if (CheckExtendedPropertyExists (tables, relations))
+ nsmgr.AddNamespace (XmlConstants.MspropPrefix, XmlConstants.MspropNamespace);
+
+ if (atts.Count > 0)
+ schema.UnhandledAttributes = atts.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
- schema.UnhandledAttributes = new XmlAttribute[] {xmlnsAttr};
-
XmlSchemaElement elem = new XmlSchemaElement ();
elem.Name = XmlConvert.EncodeName (DataSetName);
- XmlAttribute[] atts = new XmlAttribute [2];
- atts[0] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace);
- atts[0].Value = "true";
+ // Add namespaces used in DataSet components (tables, columns, ...)
+ foreach (DataTable dt in tables) {
+ foreach (DataColumn col in dt.Columns)
+ CheckNamespace (col.Prefix, col.Namespace, nsmgr, schema);
+ CheckNamespace (dt.Prefix, dt.Namespace, nsmgr, schema);
+ }
- atts[1] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace);
- atts[1].Value = locale.Name;
- elem.UnhandledAttributes = atts;
+ // Attributes for DataSet element
+ atts.Clear ();
+ attr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace);
+ attr.Value = "true";
+ atts.Add (attr);
- schema.Items.Add (elem);
+ attr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace);
+ attr.Value = locale.Name;
+ atts.Add (attr);
+
+ elem.UnhandledAttributes = atts.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
+
+ AddExtendedPropertyAttributes (elem, ExtendedProperties, doc);
XmlSchemaComplexType complex = new XmlSchemaComplexType ();
elem.SchemaType = complex;
}
}
- if (isTopLevel){
- choice.Items.Add (GetTableSchema (doc, table));
+ if (isTopLevel) {
+ if (table.Namespace != SafeNS (schema.TargetNamespace)) {
+ XmlSchemaElement extElem = new XmlSchemaElement ();
+ extElem.RefName = new XmlQualifiedName (table.TableName, table.Namespace);
+ choice.Items.Add (extElem);
+ }
+ else
+ choice.Items.Add (GetTableSchema (doc, table, schema, nsmgr));
}
}
+
+ schema.Items.Add (elem);
- AddConstraintsToSchema (elem, constraintPrefix, tables, relations);
+ AddConstraintsToSchema (elem, constraintPrefix, tables, relations, doc);
+ foreach (string prefix in nsmgr) {
+ string ns = nsmgr.LookupNamespace (nsmgr.NameTable.Get (prefix));
+ if (prefix != "xmlns" && prefix != "xml" && ns != null && ns != String.Empty)
+ schema.Namespaces.Add (prefix, ns);
+ }
+
return schema;
}
-
+
+ private bool CheckExtendedPropertyExists (
+ DataTableCollection tables,
+ DataRelationCollection relations)
+ {
+ if (ExtendedProperties.Count > 0)
+ return true;
+ foreach (DataTable dt in tables) {
+ if (dt.ExtendedProperties.Count > 0)
+ return true;
+ foreach (DataColumn col in dt.Columns)
+ if (col.ExtendedProperties.Count > 0)
+ return true;
+ foreach (Constraint c in dt.Constraints)
+ if (c.ExtendedProperties.Count > 0)
+ return true;
+ }
+ if (relations == null)
+ return false;
+ foreach (DataRelation rel in relations)
+ if (rel.ExtendedProperties.Count > 0)
+ return true;
+ return false;
+ }
+
// Add all constraints in all tables to the schema.
- private void AddConstraintsToSchema (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, DataRelationCollection relations)
+ private void AddConstraintsToSchema (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, DataRelationCollection relations, XmlDocument doc)
{
// first add all unique constraints.
- Hashtable uniqueNames = AddUniqueConstraints (elem, constraintPrefix, tables);
+ Hashtable uniqueNames = AddUniqueConstraints (elem, constraintPrefix, tables, doc);
// Add all foriegn key constraints.
- AddForeignKeys (uniqueNames, elem, constraintPrefix, relations);
+ AddForeignKeys (uniqueNames, elem, constraintPrefix, relations, doc);
}
// Add unique constaraints to the schema.
// return hashtable with the names of all XmlSchemaUnique elements we created.
- private Hashtable AddUniqueConstraints (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables)
+ private Hashtable AddUniqueConstraints (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, XmlDocument doc)
{
- XmlDocument doc = new XmlDocument();
Hashtable uniqueNames = new Hashtable();
foreach (DataTable table in tables) {
- foreach (Constraint constaint in table.Constraints) {
+ foreach (Constraint constraint in table.Constraints) {
- if (constaint is UniqueConstraint) {
+ if (constraint is UniqueConstraint) {
ArrayList attrs = new ArrayList ();
XmlAttribute attrib;
- UniqueConstraint uqConst = (UniqueConstraint)constaint;
+ UniqueConstraint uqConst = (UniqueConstraint) constraint;
XmlSchemaUnique uniq = new XmlSchemaUnique ();
// if column of the constraint is hidden do not write the constraint.
XmlSchemaXPath field;
foreach (DataColumn column in uqConst.Columns) {
field = new XmlSchemaXPath();
- field.XPath = constraintPrefix+column.ColumnName;
+ string typePrefix = column.ColumnMapping == MappingType.Attribute ? "@" : "";
+ field.XPath = typePrefix + constraintPrefix+column.ColumnName;
uniq.Fields.Add(field);
}
+ AddExtendedPropertyAttributes (uniq, constraint.ExtendedProperties, doc);
+
elem.Constraints.Add (uniq);
uniqueNames.Add (uniq.Name, null);
}
}
// Add the foriegn keys to the schema.
- private void AddForeignKeys (Hashtable uniqueNames, XmlSchemaElement elem, string constraintPrefix, DataRelationCollection relations)
+ private void AddForeignKeys (Hashtable uniqueNames, XmlSchemaElement elem, string constraintPrefix, DataRelationCollection relations, XmlDocument doc)
{
if (relations == null) return;
- XmlDocument doc = new XmlDocument();
foreach (DataRelation rel in relations) {
if (rel.ParentKeyConstraint == null || rel.ChildKeyConstraint == null)
continue;
+
+ bool isHidden = false;
+ foreach (DataColumn col in rel.ParentColumns) {
+ if (col.ColumnMapping == MappingType.Hidden) {
+ isHidden = true;
+ break;
+ }
+ }
+ foreach (DataColumn col in rel.ChildColumns) {
+ if (col.ColumnMapping == MappingType.Hidden) {
+ isHidden = true;
+ break;
+ }
+ }
+ if (isHidden)
+ continue;
ArrayList attrs = new ArrayList ();
XmlAttribute attrib;
XmlSchemaXPath field;
foreach (DataColumn column in rel.ChildColumns) {
field = new XmlSchemaXPath();
- field.XPath = constraintPrefix+column.ColumnName;
+ string typePrefix = column.ColumnMapping == MappingType.Attribute ? "@" : "";
+ field.XPath = typePrefix + constraintPrefix + column.ColumnName;
keyRef.Fields.Add(field);
}
+
keyRef.UnhandledAttributes = (XmlAttribute[])attrs.ToArray (typeof (XmlAttribute));
+ AddExtendedPropertyAttributes (keyRef, rel.ExtendedProperties, doc);
+
elem.Constraints.Add (keyRef);
}
}
- private XmlSchemaElement GetTableSchema (XmlDocument doc, DataTable table)
+ private XmlSchemaElement GetTableSchema (XmlDocument doc, DataTable table, XmlSchema schemaToAdd, XmlNamespaceManager nsmgr)
{
ArrayList elements;
ArrayList atts;
DataColumn simple;
-
+
+ ArrayList xattrs = new ArrayList();
+ XmlAttribute xattr;
+
SplitColumns (table, out atts, out elements, out simple);
XmlSchemaElement elem = new XmlSchemaElement ();
XmlSchemaComplexType complex = new XmlSchemaComplexType ();
elem.SchemaType = complex;
- //TODO - what about the simple content?
+ XmlSchemaObjectCollection schemaAttributes = null;
+
if (simple != null) {
// add simpleContent
XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
// add ordinal attribute
xlmAttrs[1] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Ordinal, XmlConstants.MsdataNamespace);
- xlmAttrs[1].Value = simple.Ordinal.ToString();
+ xlmAttrs[1].Value = XmlConvert.ToString (simple.Ordinal);
simpleContent.UnhandledAttributes = xlmAttrs;
XmlSchemaSimpleContentExtension extension = new XmlSchemaSimpleContentExtension();
simpleContent.Content = extension;
extension.BaseTypeName = MapType (simple.DataType);
-
- }
- else {
+ schemaAttributes = extension.Attributes;
+ } else {
+ schemaAttributes = complex.Attributes;
//A sequence of element types or a simple content node
//<xs:sequence>
XmlSchemaSequence seq = new XmlSchemaSequence ();
- complex.Particle = seq;
foreach (DataColumn col in elements) {
// Add element for the column.
XmlSchemaElement colElem = new XmlSchemaElement ();
- ArrayList xattrs = new ArrayList();
- XmlAttribute xattr;
colElem.Name = col.ColumnName;
if (col.ColumnName != col.Caption && col.Caption != String.Empty) {
if (col.AutoIncrementSeed != 0) {
xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.AutoIncrementSeed, XmlConstants.MsdataNamespace);
- xattr.Value = col.AutoIncrementSeed.ToString();
+ xattr.Value = XmlConvert.ToString (col.AutoIncrementSeed);
xattrs.Add (xattr);
}
if (col.DefaultValue.ToString () != String.Empty)
- colElem.DefaultValue = col.DefaultValue.ToString ();
-
+ colElem.DefaultValue = WriteObjectXml (col.DefaultValue);
+
+ if (col.ReadOnly) {
+ xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.ReadOnly, XmlConstants.MsdataNamespace);
+ xattr.Value = "true";
+ xattrs.Add (xattr);
+ }
+
if (col.MaxLength < 0)
colElem.SchemaTypeName = MapType (col.DataType);
if (colElem.SchemaTypeName == XmlConstants.QnString && col.DataType != typeof (string)
&& col.DataType != typeof (char)) {
xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.DataType, XmlConstants.MsdataNamespace);
- xattr.Value = col.DataType.ToString();
+ xattr.Value = col.DataType.AssemblyQualifiedName;
xattrs.Add (xattr);
}
}
colElem.UnhandledAttributes = (XmlAttribute[])xattrs.ToArray(typeof (XmlAttribute));
+ xattrs.Clear ();
+ AddExtendedPropertyAttributes (colElem, col.ExtendedProperties, doc);
seq.Items.Add (colElem);
}
foreach (DataRelation rel in table.ChildRelations) {
if (rel.Nested) {
- seq.Items.Add(GetTableSchema (doc, rel.ChildTable));
+ if (rel.ChildTable.Namespace != SafeNS (schemaToAdd.TargetNamespace)) {
+ XmlSchemaElement el = new XmlSchemaElement ();
+ el.RefName = new XmlQualifiedName (rel.ChildTable.TableName, rel.ChildTable.Namespace);
+ } else {
+ XmlSchemaElement el = GetTableSchema (doc, rel.ChildTable, schemaToAdd, nsmgr);
+ el.MinOccurs = 0;
+ el.MaxOccursString = "unbounded";
+ XmlSchemaComplexType ct = (XmlSchemaComplexType) el.SchemaType;
+ ct.Name = el.Name;
+ el.SchemaType = null;
+ el.SchemaTypeName = new XmlQualifiedName (ct.Name, schemaToAdd.TargetNamespace);
+ schemaToAdd.Items.Add (ct);
+ seq.Items.Add (el);
+ }
}
}
+
+ if (seq.Items.Count > 0)
+ complex.Particle = seq;
}
//Then a list of attributes
//<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
XmlSchemaAttribute att = new XmlSchemaAttribute ();
att.Name = col.ColumnName;
- att.Form = XmlSchemaForm.Unqualified;
- att.SchemaTypeName = MapType (col.DataType);
- complex.Attributes.Add (att);
+ if (col.Namespace != String.Empty) {
+ att.Form = XmlSchemaForm.Qualified;
+ string prefix = col.Prefix == String.Empty ? "app" + schemaToAdd.Namespaces.Count : col.Prefix;
+ att.Name = prefix + ":" + col.ColumnName;
+ // FIXME: Handle prefix mapping correctly.
+ schemaToAdd.Namespaces.Add (prefix, col.Namespace);
+ }
+ if (!col.AllowDBNull)
+ att.Use = XmlSchemaUse.Required;
+ if (col.DefaultValue.ToString () != String.Empty)
+ att.DefaultValue = WriteObjectXml (col.DefaultValue);
+
+ if (col.ReadOnly) {
+ xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.ReadOnly, XmlConstants.MsdataNamespace);
+ xattr.Value = "true";
+ xattrs.Add (xattr);
+ }
+
+ att.UnhandledAttributes = xattrs.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
+ xattrs.Clear ();
+
+ if (col.MaxLength > -1)
+ att.SchemaType = GetTableSimpleType (doc, col);
+ else
+ att.SchemaTypeName = MapType (col.DataType);
+ // FIXME: what happens if extended properties are set on attribute columns??
+ schemaAttributes.Add (att);
}
+ AddExtendedPropertyAttributes (elem, table.ExtendedProperties, doc);
+
return elem;
}
+ private void AddExtendedPropertyAttributes (XmlSchemaAnnotated xsobj, PropertyCollection props, XmlDocument doc)
+ {
+ ArrayList attList = new ArrayList ();
+ XmlAttribute xmlAttr;
+
+ if (xsobj.UnhandledAttributes != null)
+ attList.AddRange (xsobj.UnhandledAttributes);
+
+ // add extended properties to xs:element
+ foreach (DictionaryEntry de in props) {
+ xmlAttr = doc.CreateAttribute (XmlConstants.MspropPrefix, XmlConvert.EncodeName (de.Key.ToString ()), XmlConstants.MspropNamespace);
+ xmlAttr.Value = de.Value != null ? WriteObjectXml (de.Value) : String.Empty;
+ attList.Add (xmlAttr);
+ }
+ if (attList.Count > 0)
+ xsobj.UnhandledAttributes = attList.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
+ }
+
+ private string SafeNS (string ns)
+ {
+ return ns != null ? ns : String.Empty;
+ }
+
+ private void HandleExternalNamespace (string prefix, string ns, XmlSchema schema)
+ {
+ foreach (XmlSchemaExternal ext in schema.Includes) {
+ XmlSchemaImport imp = ext as XmlSchemaImport;
+ if (imp != null && imp.Namespace == ns)
+ return; // nothing to do
+ }
+ XmlSchemaImport i = new XmlSchemaImport ();
+ i.Namespace = ns;
+ i.SchemaLocation = "_" + prefix + ".xsd";
+ schema.Includes.Add (i);
+ }
+
private XmlSchemaSimpleType GetTableSimpleType (XmlDocument doc, DataColumn col)
{
// SimpleType