| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- // Author:
- // Patrick Earl <[email protected]>
- //
- // Copyright (c) 2006
- //
- // 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.
- //
- #if NET_2_0
- using System;
- using System.Data;
- using System.IO;
- using System.Text.RegularExpressions;
- using System.Xml;
- using NUnit.Framework;
- namespace MonoTests.System.Data
- {
- [TestFixture]
- public class DataTableReadWriteXmlTest
- {
- void StandardizeXmlFormat(ref string xml)
- {
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(xml);
- StringWriter sw = new StringWriter();
- doc.Save(sw);
- xml = sw.ToString();
- }
-
- void GenerateTestData(out DataSet ds,
- out DataTable dtMainInDS,
- out DataTable dtChildInDS,
- out DataTable dtMain)
- {
- ds = new DataSet("MyDataSet");
- // Create a primary table and populate it with some data. Make a
- // copy of the primary table and put it into the dataset.
- dtMain = new DataTable("Main");
- dtMain.Columns.Add(new DataColumn("ID", typeof(int)));
- dtMain.Columns.Add(new DataColumn("Data", typeof(string)));
-
- DataRow row = dtMain.NewRow();
- row["ID"] = 1;
- row["Data"] = "One";
- dtMain.Rows.Add(row);
-
- row = dtMain.NewRow();
- row["ID"] = 2;
- row["Data"] = "Two";
- dtMain.Rows.Add(row);
-
- row = dtMain.NewRow();
- row["ID"] = 3;
- row["Data"] = "Three";
- dtMain.Rows.Add(row);
-
- dtMainInDS = dtMain.Copy();
- ds.Tables.Add(dtMainInDS);
-
- // Create a child table. Make a copy of the child table and put
- // it into the dataset.
- dtChildInDS = new DataTable("Child");
- dtChildInDS.Columns.Add(new DataColumn("ID", typeof(int)));
- dtChildInDS.Columns.Add(new DataColumn("PID", typeof(int)));
- dtChildInDS.Columns.Add(new DataColumn("ChildData", typeof(string)));
-
- row = dtChildInDS.NewRow();
- row["ID"] = 1;
- row["PID"] = 1;
- row["ChildData"] = "Parent1Child1";
- dtChildInDS.Rows.Add(row);
-
- row = dtChildInDS.NewRow();
- row["ID"] = 2;
- row["PID"] = 1;
- row["ChildData"] = "Parent1Child2";
- dtChildInDS.Rows.Add(row);
-
- row = dtChildInDS.NewRow();
- row["ID"] = 3;
- row["PID"] = 2;
- row["ChildData"] = "Parent2Child3";
- dtChildInDS.Rows.Add(row);
-
- ds.Tables.Add(dtChildInDS);
-
- // Set up the relation in the dataset.
- ds.Relations.Add(new DataRelation("MainToChild",
- dtMainInDS.Columns["ID"],
- dtChildInDS.Columns["PID"]));
- }
-
- [Test]
- public void TestWriteXml()
- {
- DataSet ds;
- DataTable dtMainInDS, dtChildInDS, dtMain;
-
- GenerateTestData(out ds,
- out dtMainInDS,
- out dtChildInDS,
- out dtMain);
-
- StringWriter sw = new StringWriter();
-
- // Get XML for DataSet writes.
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw);
- string xmlDSNone = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw, XmlWriteMode.DiffGram);
- string xmlDSDiffGram = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw, XmlWriteMode.WriteSchema);
- string xmlDSWriteSchema = sw.ToString();
- // Get XML for recursive DataTable writes of the same data as in
- // the DataSet.
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, true);
- string xmlDTNone = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.DiffGram, true);
- string xmlDTDiffGram = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.WriteSchema, true);
- string xmlDTWriteSchema = sw.ToString();
-
- // The schema XML written by the DataTable call has an extra element
- // in the element for the dataset schema definition. We remove that
- // extra attribute and then check to see if the rest of the xml is
- // identical.
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(xmlDTWriteSchema);
- XmlNode node = doc.DocumentElement.FirstChild.FirstChild;
- XmlAttribute a = (XmlAttribute)node.Attributes.GetNamedItem("msdata:MainDataTable");
- Assert.IsNotNull(a, "Test#01");
- Assert.AreEqual("Main", a.Value, "Test#02");
-
- node.Attributes.Remove(a);
- sw.GetStringBuilder().Length = 0;
- doc.Save(sw);
- xmlDTWriteSchema = sw.ToString();
-
- StandardizeXmlFormat(ref xmlDSWriteSchema);
-
- Assert.AreEqual(xmlDSNone, xmlDTNone, "Test#03");
- Assert.AreEqual(xmlDSDiffGram, xmlDTDiffGram, "Test#04");
- Assert.AreEqual(xmlDSWriteSchema, xmlDTWriteSchema, "Test#05");
-
- // Now that we've tested writing tables (including children),
- // we will go on to test the cases where the hierarchy flag
- // is false. For this, we will test one table inside the
- // dataset and one table outside the dataset.
-
- // First, we fix our test DataSet to only have a single table
- // with no relations. Then, we go about comparing the XML.
- // Get XML for DataSet writes.
- ds.Tables[1].Constraints.Remove(ds.Tables[1].Constraints[0]);
- ds.Tables[0].Constraints.Remove(ds.Tables[0].Constraints[0]);
- ds.Tables[0].ChildRelations.Remove("MainToChild");
- ds.Tables.Remove("Child");
-
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw);
- xmlDSNone = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw, XmlWriteMode.DiffGram);
- xmlDSDiffGram = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- ds.WriteXml(sw, XmlWriteMode.WriteSchema);
- xmlDSWriteSchema = sw.ToString();
-
- // Get all the DataTable.WriteXml results.
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw);
- string xmlDTNoneInDS = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.DiffGram);
- string xmlDTDiffGramInDS = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.WriteSchema);
- string xmlDTWriteSchemaInDS = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMain.WriteXml(sw);
- string xmlDTNoneNoDS = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMain.WriteXml(sw, XmlWriteMode.DiffGram);
- string xmlDTDiffGramNoDS = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMain.WriteXml(sw, XmlWriteMode.WriteSchema);
- string xmlDTWriteSchemaNoDS = sw.ToString();
-
- Assert.AreEqual(xmlDSNone, xmlDTNoneInDS, "Test#06");
- // The only difference between the xml output from inside the
- // dataset and the xml output from outside the dataset is that
- // there's a fake <DocumentElement> tag surrounding tbe table
- // in the second case. We replace it with the name of the
- // dataset for testing purposes.
- doc.LoadXml(xmlDTNoneNoDS);
- Assert.AreEqual("DocumentElement", doc.DocumentElement.Name, "Test#07");
- sw.GetStringBuilder().Length = 0;
- doc.Save(sw);
- xmlDTNoneNoDS = sw.ToString();
- xmlDTNoneNoDS = xmlDTNoneNoDS.Replace("<DocumentElement>", "<MyDataSet>");
- xmlDTNoneNoDS = xmlDTNoneNoDS.Replace("</DocumentElement>", "</MyDataSet>");
-
- StandardizeXmlFormat(ref xmlDSNone);
-
- Assert.AreEqual(xmlDSNone, xmlDTNoneNoDS, "Test#08");
-
- // Now check the DiffGram.
- Assert.AreEqual(xmlDSDiffGram, xmlDTDiffGramInDS, "Test#09");
-
- doc.LoadXml(xmlDTDiffGramNoDS);
- Assert.AreEqual("DocumentElement", doc.DocumentElement.FirstChild.Name, "Test#10");
- xmlDTDiffGramNoDS = xmlDTDiffGramNoDS.Replace("<DocumentElement>", "<MyDataSet>");
- xmlDTDiffGramNoDS = xmlDTDiffGramNoDS.Replace("</DocumentElement>", "</MyDataSet>");
- Assert.AreEqual(xmlDSDiffGram, xmlDTDiffGramNoDS, "Test#11");
-
- // Finally we check the WriteSchema version of the data. First
- // we remove the extra "msdata:MainDataTable" attribute from
- // the schema declaration part of the DataTable xml.
- doc = new XmlDocument();
- doc.LoadXml(xmlDTWriteSchemaInDS);
- node = doc.DocumentElement.FirstChild.FirstChild;
- a = (XmlAttribute)node.Attributes.GetNamedItem("msdata:MainDataTable");
- Assert.IsNotNull(a, "Test#12");
- Assert.AreEqual("Main", a.Value, "Test#13");
- node.Attributes.Remove(a);
- sw.GetStringBuilder().Length = 0;
- doc.Save(sw);
- xmlDTWriteSchemaInDS = sw.ToString();
-
- StandardizeXmlFormat(ref xmlDSWriteSchema);
- Assert.AreEqual(xmlDSWriteSchema, xmlDTWriteSchemaInDS, "Test#14");
-
- // Remove the extra "msdata:MainDataTable" for the other test case.
- // Also make sure we have "NewDataSet" in the appropriate locations.
- doc = new XmlDocument();
- doc.LoadXml(xmlDTWriteSchemaNoDS);
- node = doc.DocumentElement.FirstChild.FirstChild;
- a = (XmlAttribute)node.Attributes.GetNamedItem("msdata:MainDataTable");
- Assert.IsNotNull(a, "Test#15");
- Assert.AreEqual("Main", a.Value, "Test#16");
- node.Attributes.Remove(a);
- sw.GetStringBuilder().Length = 0;
- doc.Save(sw);
-
- Assert.AreEqual("NewDataSet", doc.DocumentElement.Name, "Test#17");
- Assert.AreEqual("NewDataSet", doc.DocumentElement.FirstChild.Attributes["id"].Value, "Test#18");
- Assert.AreEqual("NewDataSet", doc.DocumentElement.FirstChild.FirstChild.Attributes["name"].Value, "Test#19");
-
- xmlDTWriteSchemaNoDS = sw.ToString();
-
- xmlDTWriteSchemaNoDS = xmlDTWriteSchemaNoDS.Replace("<NewDataSet>","<MyDataSet>");
- xmlDTWriteSchemaNoDS = xmlDTWriteSchemaNoDS.Replace("</NewDataSet>","</MyDataSet>");
- xmlDTWriteSchemaNoDS = xmlDTWriteSchemaNoDS.Replace("\"NewDataSet\"","\"MyDataSet\"");
- Assert.AreEqual(xmlDSWriteSchema, xmlDTWriteSchemaNoDS, "Test#20");
- }
-
- [Test]
- [ExpectedException (typeof (NotImplementedException))]
- #if TARGET_JVM
- [Ignore ("Should review the test")]
- #endif
- public void TestReadXml()
- {
- // For reading, DataTable.ReadXml only supports reading in xml with
- // the schema included. This means that we can only read in XML
- // that was generated with the WriteSchema flag.
- DataSet ds;
- DataTable dtMainInDS, dtChildInDS, dtMain;
-
- GenerateTestData(out ds,
- out dtMainInDS,
- out dtChildInDS,
- out dtMain);
-
- StringWriter sw = new StringWriter();
-
- // Get XML for recursive DataTable writes of the same data as in
- // the DataSet.
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, true);
- string xmlDTNone = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.DiffGram, true);
- string xmlDTDiffGram = sw.ToString();
- sw.GetStringBuilder().Length = 0;
- dtMainInDS.WriteXml(sw, XmlWriteMode.WriteSchema, true);
- string xmlMultiTable = sw.ToString();
-
- sw.GetStringBuilder().Length = 0;
- dtMain.WriteXml(sw, XmlWriteMode.WriteSchema);
- string xmlSingleTable = sw.ToString();
-
- DataTable newdt = new DataTable();
- try {
- newdt.ReadXml(new StringReader(xmlDTNone));
- Assert.Fail("Test#01");
- } catch(InvalidOperationException) {
- // DataTable does not support schema inference from Xml.
- }
-
- try {
- newdt.ReadXml(new StringReader(xmlDTDiffGram));
- Assert.Fail("Test#02");
- } catch(InvalidOperationException) {
- // DataTable does not support schema inference from Xml.
- }
-
- DataTable multiTable = new DataTable();
- multiTable.ReadXml(new StringReader(xmlMultiTable));
- // Do some simple checks to see if the main dataset was created
- // and if there are relationships present.
- Assert.AreEqual("MyDataSet", multiTable.DataSet.DataSetName, "Test#03");
- Assert.AreEqual(1, multiTable.ChildRelations.Count, "Test#04");
- Assert.AreEqual(1, multiTable.Constraints.Count, "Test#05");
- // Write the table back out and check to see that the XML is
- // the same as before.
- sw.GetStringBuilder().Length = 0;
- multiTable.WriteXml(sw, XmlWriteMode.WriteSchema, true);
- string xmlMultiTableCheck = sw.ToString();
- Assert.AreEqual(xmlMultiTable, xmlMultiTableCheck, "Test#06");
-
- DataTable singleTable = new DataTable();
- singleTable.ReadXml(new StringReader(xmlSingleTable));
- // Do some simple checks on the table.
- Assert.IsNull(singleTable.DataSet, "Test#07");
- Assert.AreEqual("Main", singleTable.TableName, "Test#08");
- // Write the table out and check if it's the same.
- sw.GetStringBuilder().Length = 0;
- singleTable.WriteXml(sw, XmlWriteMode.WriteSchema);
- string xmlSingleTableCheck = sw.ToString();
- Assert.AreEqual(xmlSingleTable, xmlSingleTableCheck, "Test#09");
- }
- }
- }
- #endif
|