2 // mcs/class/System.Data/System.Data/XmlDiffLoader.cs
4 // Purpose: Loads XmlDiffGrams to DataSet
6 // class: XmlDiffLoader
7 // assembly: System.Data.dll
8 // namespace: System.Data
11 // Ville Palo <vi64pa@koti.soon.fi>
13 // (c)copyright 2003 Ville Palo
18 using System.Xml.XPath;
19 using System.Collections;
20 using System.Globalization;
22 namespace System.Data {
24 internal class XmlDiffLoader
28 enum LoadType {CURRENT, BEFORE, ERROR};
30 private Hashtable DiffGrRows = new Hashtable ();
31 private Hashtable ErrorRows = new Hashtable ();
37 public XmlDiffLoader (DataSet DSet)
44 #region Public methods
46 public void Load (XmlReader Reader)
49 XmlDocument Document = XmlDataLoader.buildXmlDocument(Reader);
51 XPathNavigator Navigator = Document.CreateNavigator ();
52 bool origEnforceConstraint = DSet.EnforceConstraints;
53 DSet.EnforceConstraints = false;
54 LoadBefore (Navigator);
55 LoadCurrent (Navigator);
56 LoadErrors (Navigator);
57 DSet.EnforceConstraints = origEnforceConstraint;
60 #endregion // Public methods
62 #region Private methods
64 private void LoadCurrent (XPathNavigator Navigator)
66 Navigator.MoveToRoot ();
68 if (Navigator.MoveToFirstChild ()) {
70 if (Navigator.Name == "diffgr:diffgram") {
72 if (Navigator.MoveToFirstChild ()) {
74 if (Navigator.MoveToFirstChild ()) {
76 if (DSet.Tables.Contains (Navigator.LocalName))
77 LoadCurrentTable(Navigator);
79 throw new DataException (Locale.GetText ("Cannot load diffGram. Table '" + Navigator.LocalName + "' is missing in the destination dataset"));
80 }while (Navigator.MoveToNext());
87 private void LoadBefore (XPathNavigator Navigator)
89 Navigator.MoveToRoot ();
91 if (!Navigator.MoveToFirstChild ())
92 return; // FIXME: exception
94 if (Navigator.Name != "diffgr:diffgram")
95 return; // FIXME: exception
97 if (Navigator.MoveToFirstChild ()) {
99 while (Navigator.Name != "diffgr:before") {
101 if (!Navigator.MoveToNext ()) // there is no before
105 if (Navigator.MoveToFirstChild ()) {
108 if (DSet.Tables.Contains (Navigator.LocalName))
109 LoadBeforeTable(Navigator);
111 throw new DataException (Locale.GetText ("Cannot load diffGram. Table '" + Navigator.LocalName + "' is missing in the destination dataset"));
112 } while (Navigator.MoveToNext ());
118 private void LoadErrors (XPathNavigator Navigator)
120 Navigator.MoveToRoot ();
122 if (!Navigator.MoveToFirstChild ())
123 return; // FIXME: exception
125 if (Navigator.Name != "diffgr:diffgram")
126 return; // FIXME: exception
128 if (Navigator.MoveToFirstChild ()) {
130 while (Navigator.Name != "diffgr:errors") {
131 if (!Navigator.MoveToNext ())
135 if (Navigator.MoveToFirstChild ()) {
139 // find the row in 'current' section
140 if (Navigator.MoveToFirstAttribute ()) {
143 if (Navigator.Name == "diffgr:id") {
145 if (ErrorRows.Contains (Navigator.Value))
146 Row = (DataRow)ErrorRows [Navigator.Value];
149 } while (Navigator.MoveToNextAttribute ());
151 Navigator.MoveToParent ();
154 if (Navigator.MoveToFirstChild ()) {
159 if (Navigator.MoveToFirstAttribute ()) {
161 if (Navigator.Name == "diffgr:Error")
162 Error = Navigator.Value;
164 } while (Navigator.MoveToNextAttribute ());
166 Navigator.MoveToParent ();
169 Row.SetColumnError (Navigator.LocalName, Error);
171 } while (Navigator.MoveToNext ());
177 private void LoadColumns (DataTable Table, DataRow Row, XPathNavigator Navigator, bool NewRow, LoadType loadType)
179 if (Navigator.MoveToFirstChild ()) {
182 if (Table.Columns.Contains (Navigator.LocalName))
183 Row [Navigator.LocalName] = Navigator.Value;
184 else if (DSet.Tables.Contains (Navigator.LocalName)){
185 if (loadType == LoadType.BEFORE)
186 LoadBeforeTable(Navigator);
187 else if (loadType == LoadType.CURRENT)
188 LoadCurrentTable(Navigator);
191 } while (Navigator.MoveToNext ());
194 Table.Rows.Add (Row);
198 private void LoadBeforeTable (XPathNavigator Navigator)
202 DataTable Table = DSet.Tables [Navigator.LocalName];
203 DataRow Row = Table.NewRow ();
205 if (Navigator.MoveToFirstAttribute ()) {
208 if (Navigator.Name == "diffgr:id")
209 id = Navigator.Value;
211 } while (Navigator.MoveToNextAttribute ());
213 Navigator.MoveToParent ();
216 LoadColumns (Table, Row, Navigator, true, LoadType.BEFORE);
217 DiffGrRows.Add (id, Row); // for later use
218 Row.AcceptChanges ();
221 private void LoadCurrentTable (XPathNavigator Navigator)
224 DataTable Table = DSet.Tables [Navigator.LocalName];
227 bool HasErrors = false;
230 if (Navigator.MoveToFirstAttribute ()) {
233 // Find out was there same row in 'before' section
234 if (Navigator.LocalName == "id") {
235 id = Navigator.Value;
236 if (DiffGrRows.Contains (id))
237 Row = (DataRow)DiffGrRows [id];
240 else if (Navigator.LocalName == "hasErrors" && String.Compare (Navigator.Value, "true", true) == 0)
242 } while (Navigator.MoveToNextAttribute ());
245 Navigator.MoveToParent ();
249 Row = Table.NewRow ();
253 LoadColumns (Table, Row, Navigator, NewRow, LoadType.CURRENT);
256 Navigator.MoveToParent();
258 if (HasErrors) // If row had errors add row to hashtable for later use
259 ErrorRows.Add (id, Row);
264 #endregion // Private methods