views:

76

answers:

3

The goal is to populate a dataset from XML, sort one of the DataTables, and then write out the sorted DataSet back to XML.

I can't seem to sort my DataSet and have tried a few variations. It adds the data fine but does not sort. Hope someone could help to stop me pulling my hair out.

DataSet dsXml = new DataSet();
dsXml.ReadXml(msXml);
DataTable tbl;
// Read DataTable.
tbl = dsXml.Tables["cj"];
// Set Primary Key
tbl.PrimaryKey = new DataColumn[] { tbl.Columns["a"] };
DataView dtView = tbl.DefaultView;
DataRow foundRow = tbl.Rows.Find(findCookiejarId);
tbl.Rows.Add(addRow);
dtView.ToTable().Sort = "a ASC";
StringWriter sw = new StringWriter();
dsXml.WriteXml(sw);

UPDATE

Now it removes the other tables from the dataset. This is how the xml should look:

<user_data>
  <settings>
    <a></a>
    <b></b>
    <c></c>
  </settings>
  <perms>
    <a></a>
    <b></b>
    <c></c>
  </perms>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
</user_data>

And it looks like this, removing the other tables but the sort works fine :)

</DocumentElement>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
  <cj>
    <a></a>
    <b></b>
    <c></c>
  </cj>
</DocumentElement>

How can I use C# to sort just DataTable cj, and then write the entire DataSet back to XML? The settings and perms should remain untouched.

A: 

The DataView that you created reflects the sorted results, not the underlying dataset.

BC
+1  A: 

You've successfully applied the sort to the DataView. Use the DataView's .ToTable() method, and then use the Table's .WriteXML() method to output to a file.

dtView.ToTable().WriteXml(sw);
p.campbell
Thanks it hit the spot! Was playing with it for an hour or so :)
arbme
Do you know why it is replacing my root node in the xml with <DocumentElement> when it should be <Data>?
arbme
@arbme: common suggestions are to add the DataTable returned from `ToTable()` to a brand new `DataSet`. From there, name the DataSet, and `DocumentElement` will be changed to the name of the DataSet. Then call `WriteXml`, and perhaps it will be shaped as you expect.
p.campbell
+1  A: 

One way to achieve your goal is to:

  • load the sorted CJ entities into a new DataTable
  • remove the unsorted from the original DataSet
  • repopulate the DataSet with the new set of sorted CJs

Here's the proof-of-concept for sorting on pastebin. I used this XML with the proof. The output is shown sorted as you'd expect.

DataSet ds = new DataSet();
ds.ReadXml(@"D:\foo.xml");
DataTable tbl = ds.Tables["cj"];
tbl.PrimaryKey = new DataColumn[] { tbl.Columns["a"] };
DataView view = tbl.DefaultView;
view.Sort = "a ASC";
DataTable sortedBy_a = view.ToTable();

//remove all the CJ tables -- they're currently unsorted
ds.Tables.Remove("cj");

//add in all the sorted CJ tables
ds.Tables.Add(sortedBy_a);

StringWriter sw = new StringWriter();
ds.WriteXml(sw);
p.campbell
@p.campbell: Thank you very much sir, just the job!
arbme