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
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)
48 XmlTextReader TextReader = new XmlTextReader (Reader.BaseURI);
49 XmlDocument Document = new XmlDocument ();
50 Document.Load (TextReader);
53 XPathNavigator Navigator = Document.CreateNavigator ();
54 LoadBefore (Navigator);
55 LoadCurrent (Navigator);
56 LoadErrors (Navigator);
59 #endregion // Public methods
61 #region Private methods
63 private void LoadCurrent (XPathNavigator Navigator)
65 Navigator.MoveToRoot ();
67 if (Navigator.MoveToFirstChild ()) {
69 if (Navigator.Name == "diffgr:diffgram") {
71 if (Navigator.MoveToFirstChild ()) {
73 if (Navigator.MoveToFirstChild ()) {
75 if (DSet.Tables.Contains (Navigator.LocalName)) {
77 DataTable Table = DSet.Tables [Navigator.LocalName];
80 bool HasErrors = false;
83 if (Navigator.MoveToFirstAttribute ()) {
86 // Find out was there same row in 'before' section
87 if (Navigator.LocalName == "id") {
89 if (DiffGrRows.Contains (id))
90 Row = (DataRow)DiffGrRows [id];
93 else if (Navigator.LocalName == "hasErrors" && String.Compare (Navigator.Value, "true", true) == 0)
95 } while (Navigator.MoveToNextAttribute ());
98 Navigator.MoveToParent ();
103 Row = Table.NewRow ();
107 LoadColumns (Table, Row, Navigator, NewRow);
109 if (HasErrors) // If row had errors add row to hashtable for later use
110 ErrorRows.Add (id, Row);
118 private void LoadBefore (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:before") {
132 if (!Navigator.MoveToNext ()) // there is no before
136 if (Navigator.MoveToFirstChild ()) {
139 if (DSet.Tables.Contains (Navigator.LocalName)) {
142 DataTable Table = DSet.Tables [Navigator.LocalName];
143 DataRow Row = Table.NewRow ();
145 if (Navigator.MoveToFirstAttribute ()) {
148 if (Navigator.Name == "diffgr:id")
149 id = Navigator.Value;
151 } while (Navigator.MoveToNextAttribute ());
153 Navigator.MoveToParent ();
156 LoadColumns (Table, Row, Navigator, true);
157 DiffGrRows.Add (id, Row); // for later use
158 Row.AcceptChanges ();
161 throw new DataException (Locale.GetText ("Cannot load diffGram. Table '" + Navigator.LocalName + "' is missing in the destination dataset"));
163 } while (Navigator.MoveToNext ());
169 private void LoadErrors (XPathNavigator Navigator)
171 Navigator.MoveToRoot ();
173 if (!Navigator.MoveToFirstChild ())
174 return; // FIXME: exception
176 if (Navigator.Name != "diffgr:diffgram")
177 return; // FIXME: exception
179 if (Navigator.MoveToFirstChild ()) {
181 while (Navigator.Name != "diffgr:errors") {
182 if (!Navigator.MoveToNext ())
186 if (Navigator.MoveToFirstChild ()) {
190 // find the row in 'current' section
191 if (Navigator.MoveToFirstAttribute ()) {
194 if (Navigator.Name == "diffgr:id") {
196 if (ErrorRows.Contains (Navigator.Value))
197 Row = (DataRow)ErrorRows [Navigator.Value];
200 } while (Navigator.MoveToNextAttribute ());
202 Navigator.MoveToParent ();
205 if (Navigator.MoveToFirstChild ()) {
210 if (Navigator.MoveToFirstAttribute ()) {
212 if (Navigator.Name == "diffgr:Error")
213 Error = Navigator.Value;
215 } while (Navigator.MoveToNextAttribute ());
217 Navigator.MoveToParent ();
220 Row.SetColumnError (Navigator.LocalName, Error);
222 } while (Navigator.MoveToNext ());
228 private void LoadColumns (DataTable Table, DataRow Row, XPathNavigator Navigator, bool NewRow)
230 if (Navigator.MoveToFirstChild ()) {
233 if (Table.Columns.Contains (Navigator.LocalName))
234 Row [Navigator.LocalName] = Navigator.Value;
236 } while (Navigator.MoveToNext ());
239 Table.Rows.Add (Row);
244 #endregion // Private methods