Friday, September 23, 2011

GetXml dataset method not good enough

Preface

Dataset class has GetXml method. The method takes data and creates XML.The problem is that you cannot change  XML that created by function  For example  if you created SQL statement

Select PersonId,PersonName from Employee.

You will get following XML

<newdataset>
     <table1>
        <personId >354</personId > 
        <personName >Jhon</personName 
      </table1> 
</newdataset>

But if you want to change it to


<newdataset>
     <Persons>
       <Person personId = 354 personName="Jhon" >
      </Persons> 
</newdataset>

You cannot do it.

The other problem that can happen, that if SQL statement includes Left Outer Join, and one of the field
will be Null, the field will not be included in XML.

In order to solve these issus I created my "GetXml" function . You can customize your code any way you like.

Implementation

Basically I needed to implemented this function when I created statefull mechanism between client and server. So I needed to add in each row field "StateId" that will show the status of the row.

So here is the code 

private string GetXmlFromDataset(DataSet dataSet, bool isStatefull) {
   
XmlTextWriter xwriter = null;
   
try
   
{
        xwriter
= new XmlTextWriter(new MemoryStream(), Encoding.UTF8);
        xwriter
.WriteStartElement("NewDataSet");

       
//start enumerate in table collection
       
foreach (DataTable dt in dataSet .Tables )
       
{
           
int rowNum = 0;
           
DateTime tmp = DateTime.MinValue;

           
if (isStatefull)
                dt
.Columns.Add(new DataColumn("IsDummy", typeof(bool)));

           
if (isStatefull && dt.Rows.Count == 0)
           
{
                dt
.Rows.Add(dt.NewRow());

                dt
.Rows[0]["IsDummy"] = true;
           
}

           
//start enumerate in rows collection
           
foreach (DataRow dr in dt.Rows)
           
{
               
//start <Table> element
                xwriter
.WriteStartElement(dt.TableName);
               
if (isStatefull)
               
{
                    xwriter
.WriteAttributeString("stat", "0");
                    xwriter
.WriteAttributeString("rowNum", rowNum.ToString());
               
}
               
DateTime tmpDate = DateTime.MinValue  ;
               
//start enumerate in columns collection
               
foreach (DataColumn dc in dr.Table.Columns)
               
{
                   
string colValue = String.Empty;

                   
switch (dc.DataType.Name)
                   
{
                       
case "DateTime":
                           
if (DateTime.TryParse(dr[dc, DataRowVersion.Current].ToString(), out tmpDate))
                                colValue
= tmpDate.ToString("yyyy-MM-ddTHH:mm:ss");
                           
else
                                colValue
= dr[dc, DataRowVersion.Current].ToString();
                           
break;

                       
default:
                            colValue
= dr[dc, DataRowVersion.Current].ToString();
                           
break;

                   
}

                    xwriter
.WriteStartElement(dc.ColumnName.Replace(" ","_x0020_"));
                   
if ( isStatefull || String.Compare(dc.DataType.Name, "string", true) != 0)
                   
{
                        xwriter
.WriteAttributeString("datatype", dc.DataType.Name);
                   
}
                   
if (isStatefull)
                   
{
                        xwriter
.WriteAttributeString("stat", "0");
                   
}
                    xwriter
.WriteString(colValue);
                    xwriter
.WriteEndElement();
               
}
               
//end <Table> element
                xwriter
.WriteEndElement();

                rowNum
++;
           
}
       
}

       
//end <NewDataSet> element
        xwriter
.WriteEndElement();
        xwriter
.Flush();

        xwriter
.BaseStream.Seek(0, SeekOrigin.Begin);
       
StreamReader reader = new StreamReader(xwriter.BaseStream);
       
return reader.ReadToEnd();
   
}
   
finally
   
{
       
if (xwriter != null)
       
{
            xwriter
.Close();
            xwriter
= null;
       
}
   
}
 
} 

The code iterates over the tables and build XML accrodingly.

Summary

We learned in this post how to write custom "GetXml" function.

No comments:

Post a Comment