最近在做此方面的工作,.net webService 返回的xml數據到了Delphi端就無法解析成數據源,通過將.net DataSet格式化爲Delphi可以解析的格式即可實現正常數據通信
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Xml;
namespace WDService
{
// DotNetDataSetToClientDataSet
public class DNDDSToCDS
{
public DNDDSToCDS()
{
}
public static string Buf_BuieldDbsConnString(string ASQLServer, string ADtatBase, string ADbUser, string APassword)
{
string connstring = "server={0};uid=sa;pwd={1};database={2}";
return String.Format(connstring, ASQLServer,APassword,ADtatBase);
}
/// <summary>
/// dataset輸出成Delphi的Clientdataset的XML
/// </summary>
/// <param name="ds"></param>
/// <param name="TableName"></param>
/// <returns></returns>
public static string ToClientDataSet(DataSet ds)
{
string TableName = "Table";
int FieldCount = ds.Tables[TableName].Columns.Count;
DataTable tempTable = ds.Tables[TableName];
//StringBuilder result = new StringBuilder("<?xml version=\"1.0\" standalone=\"yes\"?>");
StringBuilder result = new StringBuilder();
result.Append("<DATAPACKET Version=\"2.0\">");
result.Append("<METADATA><FIELDS>");
for (int i = 0; i < FieldCount; i++)
{
DataColumn dc = tempTable.Columns[i];
string FieldType = dc.DataType.Name.ToLower();
CreateColumnSchema(ref result, dc, FieldType);
}
result.Append("</FIELDS><PARAMS/></METADATA>");
result.Append("<ROWDATA>");
int RowCount = tempTable.Rows.Count;
for (int i = 0; i < RowCount; i++)
{
result.Append("<ROW ");
for (int j = 0; j < FieldCount; j++)
{
string value = "";
if (tempTable.Rows[i].RowState == DataRowState.Deleted)
break;
switch (tempTable.Columns[j].DataType.Name.ToLower())
{
case "byte[]":
if (!Convert.IsDBNull(tempTable.Rows[i][j]))
value = encodebase64byte((byte[])tempTable.Rows[i].ItemArray[j]);
break;
case "datetime":
if (!Convert.IsDBNull(tempTable.Rows[i][j]))
{
DateTimeConverter dtc = new DateTimeConverter();
DateTime datatime = (DateTime)dtc.ConvertFromString(tempTable.Rows[i][j].ToString());
value = datatime.ToString("yyyyMMddTHH:mm:ssfff");
}
break;
default:
if (!Convert.IsDBNull(tempTable.Rows[i][j]))
{
value = tempTable.Rows[i].ItemArray[j].ToString();
value = value.Replace(">", ">");
value = value.Replace("\"", """);
}
break;
}
if (value.Length>0)
result.AppendFormat("{0}=\"{1}\" ", tempTable.Columns[j].ColumnName, value);
}
result.Append("/>");
}
result.Append("</ROWDATA></DATAPACKET>");
return result.ToString();
}
public static bool ToDotNetDataSet(string ADataXml,ref DataSet NetDataSet)
{
Boolean retv = false;
DataRow Row = null;
int RowState = 0;
string Change_Log = "";
ArrayList RowStates = new ArrayList();
DataTable TmpTable = NetDataSet.Tables[0];
ArrayList ChgRows = new ArrayList();
XmlTextReader reader = new XmlTextReader(ADataXml, XmlNodeType.Document, null);
reader.Read();
while (!reader.EOF)
{
if ((reader.NodeType == XmlNodeType.Element && reader.Name.ToUpper() == "PARAMS"))
{
if (reader.HasAttributes)
{
if (reader.MoveToFirstAttribute())
{
do
{
if (reader.Name.Equals("Change_Log", StringComparison.OrdinalIgnoreCase))
{
Change_Log = reader.Value;
break;
}
}
while (reader.MoveToNextAttribute());
}
}
}
if ((reader.NodeType == XmlNodeType.Element && reader.Name.ToUpper() == "ROW"))
{
if (reader.HasAttributes)
{
if (reader.MoveToFirstAttribute())
{
RowState = 0;
if (reader.Name.Equals("RowState", StringComparison.OrdinalIgnoreCase))
{
RowState = int.Parse(reader.Value);
reader.MoveToNextAttribute();
}
Row = TmpTable.NewRow();
do
{
DataColumn dc = TmpTable.Columns[reader.Name];
SetColumnValue(dc, ref Row, reader.Name, reader.Value);
}
while (reader.MoveToNextAttribute());
if (RowState < 3)
TmpTable.Rows.Add(Row);
else
ChgRows.Add(Row);
RowStates.Add(RowState);
}
}
}
reader.Read();
}
reader.Close();
NetDataSet.Tables[0].AcceptChanges();
if (Change_Log.Length > 0)
{
string[] Chglog = Change_Log.Split(' ');
int OldCount = NetDataSet.Tables[0].Rows.Count;
int ChgCount = Chglog.Length / 3;
int OrgNo,EndNo, OprNo;
for (int i = 0; i < ChgCount; i++)
{
DataRow NewRow;
EndNo = int.Parse(Chglog[(i + 1) * 3 - 3]);
OprNo = int.Parse(Chglog[(i + 1) * 3 - 1]);
OrgNo = EndNo;
RowState = (int)RowStates[EndNo - 1];
if (RowState == 2 || RowState == 4 || RowState == 8 || RowState == 10 || RowState == 12)
{
switch (RowState)
{
case 2: //刪除行
NetDataSet.Tables[0].Rows[OrgNo - 1].Delete();
break;
case 4: //增加新行
NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
NetDataSet.Tables[0].Rows.Add(NewRow);
break;
case 8: //修改行
OrgNo = Buf_FindOrgNo(Chglog, i + 1, OldCount);
Row = NetDataSet.Tables[0].Rows[OrgNo - 1];
NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
for (int j = 0; j < TmpTable.Columns.Count; j++)
if (!TmpTable.Columns[j].ReadOnly)
Row[j] = NewRow[j];
break;
case 10: //修改行後刪除
OrgNo = Buf_FindOrgNo(Chglog, i + 1, OldCount);
NetDataSet.Tables[0].Rows[OrgNo - 1].Delete();
break;
case 12: ///增加行後修改
NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
NetDataSet.Tables[0].Rows.Add(NewRow);
break;
}
}
}
retv = true;
}
return retv;
}
private static int Buf_FindOrgNo(string[] AChglog, int ACurrNo,int AOldCount)
{
int NewNo, OldNo, OprNo;
NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
if (OprNo == 2)
{
for (int i = ACurrNo - 1; i >= 0; i--)
{
if (NewNo == int.Parse(AChglog[i * 3 - 3]))
{
ACurrNo = i;
break;
}
}
NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
}
else if (OldNo > AOldCount)
{
for (int i = ACurrNo - 1; i >= 0; i--)
{
if (OldNo == int.Parse(AChglog[i * 3 - 3]))
{
ACurrNo = i;
break;
}
}
NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
}
if (OprNo == 8)
{
if (OldNo > AOldCount)
OldNo = Buf_FindOrgNo(AChglog, ACurrNo, AOldCount);
}
else
{
OprNo = 0;
}
return OldNo;
}
private static bool CreateColumnSchema(ref StringBuilder result, DataColumn dc, string FieldType)
{
//result.AppendFormat("<OldFIELD=\"{0}\" ", FieldType);
//Boolean,Byte,Char,DateTime,Decimal,Double,Int16,Int32,Int64,SByte,Single,String,TimeSpan,UInt16,UInt32,UInt64,Byte[]
switch (FieldType)
{
case "boolean": //Bit
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "boolean");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "byte": //Tinyint
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i2");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
if (dc.AutoIncrement)
result.Append(" SUBTYPE=\"Autoinc\"");
break;
case "int16": //smallint
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i2");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
if (dc.AutoIncrement)
result.Append(" SUBTYPE=\"Autoinc\"");
break;
case "int32": //int
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i4");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
if (dc.AutoIncrement)
result.Append(" SUBTYPE=\"Autoinc\"");
break;
case "int64": //bigint
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i8");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
if (dc.AutoIncrement)
result.Append(" SUBTYPE=\"Autoinc\"");
break;
case "datetime": //datetiem,smalldatetime
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "dateTime");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "double": //float
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "r8");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "single": //single
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "r8");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "decimal": //money,smallmoney
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" DECIMALS=\"4\" WIDTH=\"19\"", dc.ColumnName, "fixed");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "guid": // uniqueidentifier
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" SUBTYPE=\"Guid\" WIDTH=\"38\"", dc.ColumnName, "string");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "string": //char(10),varchar(50),text
if (dc.MaxLength == -1)
{
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "string");
result.AppendFormat(" WIDTH=\"{0}\"", "256");
}
else if (dc.MaxLength > 8000)
{
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" SUBTYPE=\"Text\"", dc.ColumnName, "bin.hex");
}
else
{
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "string");
result.AppendFormat(" WIDTH=\"{0}\"", dc.MaxLength);
}
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
case "byte[]": //timestamp,image,varbinay(50),binay(50)
result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" SUBTYPE=\"Binary\"", dc.ColumnName, "bin.hex");
if (dc.ReadOnly)
result.Append(" readonly=\"true\"");
break;
}
result.Append("/>");
return true;
}
private static bool SetColumnValue(DataColumn dc, ref DataRow Row, string fldname, string value)
{
switch (dc.DataType.Name.ToLower())
{
case "boolean": //Bit
//Row[fldname] = false;
if (value.Length > 0)
Row[fldname] = value.ToLower().Equals("true");
break;
case "byte": //Tinyint
if (value.Length > 0)
Row[fldname] = byte.Parse(value);
break;
case "int16": //smallint
if (value.Length > 0)
Row[fldname] = Int16.Parse(value);
break;
case "int32": //int
if (value.Length > 0)
Row[fldname] = Int32.Parse(value);
break;
case "int64": //bigint
if (value.Length > 0)
Row[fldname] = Int64.Parse(value);
break;
case "datetime": //datetiem,smalldatetime
if (value.Length > 0)
if (value.Length > 10)
Row[fldname] = DateTime.ParseExact(value, "yyyyMMddTHH:mm:ssfff", System.Globalization.CultureInfo.CurrentCulture);
else
Row[fldname] = DateTime.ParseExact(value, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
break;
case "double": //float
if (value.Length > 0)
Row[fldname] = Double.Parse(value);
break;
case "single": //single
if (value.Length > 0)
Row[fldname] = Single.Parse(value);
break;
case "decimal": //money,smallmoney
if (value.Length > 0)
Row[fldname] = Decimal.Parse(value);
break;
case "guid": // uniqueidentifier
if (value.Length > 0)
Row[fldname] = value;
break;
case "string": //char(10),varchar(50),text
if (value.Length > 0)
if (value.Length > dc.MaxLength)
Row[fldname] = value.Substring(0, dc.MaxLength);
else
Row[fldname] = value;
break;
case "byte[]": //timestamp,image,varbinay(50),binay(50)
if (value.Length > 0)
Row[fldname] = decodebase64("UTF-8", value);
break;
}
return true;
}
private static DataRow FindDataRowIndex(DataTable table, DataRow Row)
{
DataRow retv = null;
if (table.PrimaryKey.Length > 0)
{
object[] findTheseVals = new object[table.PrimaryKey.Length];
for (int i = 0; i < table.PrimaryKey.Length; i++)
findTheseVals[i] = Row[table.PrimaryKey[0].ColumnName];
retv = table.Rows.Find(findTheseVals);
}
else
{
StringBuilder expression = new StringBuilder();
foreach (DataColumn dc in table.Columns)
{
switch (dc.DataType.Name.ToLower())
{
case "boolean": //Bit
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "byte": //Tinyint
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "int16": //smallint
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "int32": //int
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "int64": //bigint
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "datetime": //datetiem,smalldatetime
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString() + "'");
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "double": //float
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "single": //single
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "decimal": //money,smallmoney
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "guid": // uniqueidentifier
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString() + "'");
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
case "string": //char(10),varchar(50),text
if (dc.MaxLength < 8000)
if (!Convert.IsDBNull(Row[dc.ColumnName]))
expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString()+"'");
else
expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
break;
}
}
DataRow[] trows = table.Select(expression.ToString().Substring(5));
if (trows.Length > 0)
retv = trows[0];
}
return retv;
}
//編碼
public static string encodebase64byte(byte[] bytes)
{
try
{
return Convert.ToBase64String(bytes);
}
catch
{
return "";
}
}
//解碼
public static byte[] decodebase64(string code_type, string code)
{
byte[] bytes = Convert.FromBase64String(code);
return bytes;
}
//解碼
public static string decodebase64_str(string code_type, string code)
{
string decode = "";
byte[] bytes = Convert.FromBase64String(code);
try
{
decode = Encoding.GetEncoding(code_type).GetString(bytes);
}
catch
{
decode = code;
}
return decode;
}
}
public class BuleSQLAccess
{
//與SQL Server的連接字符串設置
private string _connString;
private string _strSql;
private string _ErrorText;
private SqlCommandBuilder sqlCmdBuilder;
private DataSet ds = new DataSet();
private SqlDataAdapter da;
private SqlConnection GetConn()
{
try
{
SqlConnection Connection = new SqlConnection(this._connString);
Connection.Open();
return Connection;
}
catch (Exception ex)
{
_ErrorText = ex.Message;
throw;
}
}
public string ErrorText
{
get { return _ErrorText; }
}
//根據輸入的SQL語句檢索數據庫數據
public DataSet Buf_GetDataSet(string connString, string strSql, string strTableName)
{
try
{
this._connString = connString;
this._strSql = strSql;
this.da = new SqlDataAdapter(this._strSql, this.GetConn());
this.ds.Clear();
this.da.FillSchema(ds, SchemaType.Mapped, strTableName);
this.da.Fill(ds, strTableName);
return ds;//返回填充了數據的DataSet,其中數據表以strTableName給出的字符串命名
}
catch (Exception ex)
{
_ErrorText = ex.Message;
throw;
}
}
//數據庫數據更新(傳DataSet和DataTable的對象)
public DataSet Buf_PutDataSet(DataSet changedDs, string tableName)
{
try
{
this.da = new SqlDataAdapter(this._strSql, this.GetConn());
this.sqlCmdBuilder = new SqlCommandBuilder(da);
this.da.Update(changedDs, tableName);
changedDs.AcceptChanges();
return changedDs;//返回更新了的數據庫表
}
catch (Exception ex)
{
_ErrorText = ex.Message;
throw;
}
}
}
}