Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

XML String Building
By Damjan Kovac

How to build XML string with only changed rows/columns edit on user form?

Formerly I've been working on three-tier applications on J2EE platform. All aplication logic was written in EJB and all the data was send as XML string from PowerBuilder clients. I was thinking how to implement such kind of solution in .NET through ADO.NET. The most simple way is to send data as DataSet object which also includes XML represetation of containing data objects (datatables, datacolumns, etc.). But sending the whole dataset has too much overhead. We only want to send changed/modified data to middle-tier .NET component. How to do this in a efficient manner?

The basic idea is to send only changed rows/columns of DataTable object. The method below takes two parameters: - DataTable table: only changed rows from input form/datagrid
- string keyColName: name of key column of table

We use three different statuses for row tag:
- "INSERT": new added row
- "UPDATE": updated row
- "DELETE": deleted row

/// <summary>
/// Returns XML string of changed DataTable rows
/// </summary>
public string GetXML(DataTable table, string keyColName) {
 DataView ldvOriginal = new DataView(table);
 DataView ldvChanged  = new DataView(table);
 DataView ldvAdded    = new DataView(table);
 DataView ldvDeleted  = new DataView(table);
 ldvOriginal.RowStateFilter = DataViewRowState.ModifiedOriginal;
 ldvChanged.RowStateFilter  = DataViewRowState.ModifiedCurrent;
 ldvAdded.RowStateFilter    = DataViewRowState.Added;
 ldvDeleted.RowStateFilter  = DataViewRowState.Deleted;

 string lsXml = "<?xml version=\"1.0\"?>\n";
 string lsStatusInsert = "<row status=\"INSERT\">\n";
 string lsStatusUpdate = "<row status=\"UPDATE\">\n";
 string lsStatusDelete = "<row status=\"DELETE\">\n";
 int noAdded   = ldvAdded.Count;
 int noChanged = ldvChanged.Count;
 int noDeleted = ldvDeleted.Count;

 try {
  // added rows
  lsXml += "<" + table.TableName + ">\n";
  for (int i=0; i < noAdded; i++) {
   lsXml += lsStatusInsert;
   foreach (DataColumn dc in ldvAdded.Table.Columns) {
    if (ldvAdded[i][dc.ColumnName].ToString().Length > 0)
     lsXml += "<"  + dc.ColumnName + ">" +
     ldvAdded[i][dc.ColumnName] +
     "<" + dc.ColumnName + ">\n";
    } // foreach column
    lsXml += "</row>\n";
   } // for
   // modified rows
   for (int i=0; i < noChanged; i++) {
   lsXml += lsStatusUpdate;
   foreach (DataColumn dc in ldvChanged.Table.Columns) {
    if (keyColName.Equals(dc.ColumnName))
     lsXml += "<" + dc.ColumnName + ">" +
     ldvChanged[i][dc.ColumnName] +
     "<" + dc.ColumnName + ">\n";
    else
    if (!ldvOriginal[i][dc.ColumnName].ToString().Equals(ldvChanged[i][dc.ColumnName].ToString()))
     lsXml += "<"  + dc.ColumnName + ">" +
     ldvChanged[i][dc.ColumnName] +
     "<" + dc.ColumnName + ">\n";
    } // foreach column
    lsXml += "</row>\n";
   } // for 
   // deleted rows
   for (int i=0; i < noDeleted; i++) {
    lsXml += lsStatusDelete;
    lsXml += "<" + keyColName + ">" + ldvDeleted[i][keyColName] + "<" + keyColName + ">\n";  
    lsXml += "</row>\n";
   } // for 
   lsXml += "<" + table.TableName + ">\n";
 
  } catch (Exception ex) {
  throw ex;
 }
 return lsXml;
}
...

Example:

DataTable dt = new DataTable("DemoTable");
// we fill this table through DataAdapter Fill() method 
// and we edit data in user control such as DataGrid, form,..
..

if (dt.GetChanges()!=null) {
  string xml = this.GetXML(dt.GetChanges(), "customer_id");
  // pass xml to middle-tier..
  
}
Method returns XML string which can be passed to middle tier. Here we parse it and do all necessary bussiness logic due to row status. We do not need XSD because we can get metadata in the middle tier component directly from database table.