假设我有一个MS SQL Server数据库表名为" GROUPS"如下:
GROUP_ID GROUP_NAME DESCRIPTION
1 Grp1 Null
2 Grp2 Null
3 Grp3 Test
GROUP_ID是自动增量主要字段,GROUP_NAME是唯一的非null varchar字段,Description是允许空值(可选)的varchar字段。
我正在尝试将一些XML输出作为Web服务生成,以供表信息的其他进程使用。 必须以特定方式输出XML。
最终目标如下:
<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
<GROUP>
<GROUP_ID>1</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
<DESCRIPTION/>
</GROUP>
<GROUP>
<GROUP_ID>2</GROUP_ID>
<GROUP_NAME>Grp2</GROUP_NAME>
<DESCRIPTION/>
</GROUP>
<GROUP>
<GROUP_ID>3</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
<DESCRIPTION>Test</DESCRIPTION>
</GROUP>
</GROUPS>
这个程序几乎达到了预期的目标:
string sql = "SELECT * FROM GROUPS";
Response.ContentType = "application/xml"; // Set the page to output XML
SqlDataAdapter da = new SqlDataAdapter(sql, conn); // SQL Adapter, conn is an already open SQL connection
DataSet ds = new DataSet("GROUPS"); // Root Node of XML doc will be "GROUPS"
da.Fill(ds, "GROUP"); // Each record node is a "GROUP"
XmlTextWriter xml = new XmlTextWriter(Response.Output) { Formatting = Formatting.None }; // XML writer
xml.WriteStartDocument(); // XML header
ds.WriteXml(xml); // Write XML output
此过程的问题在于它不提供所需的空节点,例如表中的空值。它看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
<GROUP>
<GROUP_ID>1</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
</GROUP>
<GROUP>
<GROUP_ID>2</GROUP_ID>
<GROUP_NAME>Grp2</GROUP_NAME>
</GROUP>
<GROUP>
<GROUP_ID>3</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
<DESCRIPTION>Test</DESCRIPTION>
</GROUP>
</GROUPS>
在进行一些研究之后,尝试使用以下步骤创建所需的输出:
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM GROUPS";
SqlDataReader row = cmd.ExecuteReader();
DataSet ds = new DataSet("GROUPS");
while (row.Read())
{
DataTable table1 = new DataTable("GROUP" + row["GROUP_ID"]); // This line is the issue
object[] columns = new object[row.FieldCount];
for (int i = 0; i < row.FieldCount; i++)
{
string name = row.GetName(i);
table1.Columns.Add(name);
columns[i] = DBstr(row[i]);
}
table1.Rows.Add(columns);
ds.Tables.Add(table1);
}
row.Close();
Response.ContentType = "application/xml"; // Set the page to output XML
XmlTextWriter xml = new XmlTextWriter(Response.Output) { Formatting = Formatting.None }; // XML writer
xml.WriteStartDocument(); // XML header
ds.WriteXml(xml, XmlWriteMode.IgnoreSchema); // Write XML output
public static string DBstr(Object obj)
{
if (obj == null || obj == DBNull.Value)
{
return String.Empty; // Default value for null DB value
}
else if (obj.GetType() == typeof(DateTime))
{
return ((DateTime)obj).ToString("MM/dd/yyyy");
}
else
{
return obj.ToString();
}
}
这里的问题是我必须为每个DataTable或唯一的命名空间指定一个唯一的名称。在从DataSet写出xml之前。 所以它看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
<GROUP1>
<GROUP_ID>1</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
<DESCRIPTION/>
</GROUP1>
<GROUP2>
<GROUP_ID>2</GROUP_ID>
<GROUP_NAME>Grp2</GROUP_NAME>
<DESCRIPTION/>
</GROUP2>
<GROUP3>
<GROUP_ID>3</GROUP_ID>
<GROUP_NAME>Grp1</GROUP_NAME>
<DESCRIPTION>Test</DESCRIPTION>
</GROUP3>
</GROUPS>
或者,每个GROUP行都会抛出一个xmlns标记。
无论哪种方式,都是不受欢迎的。那么在这里使用C#获得所需目标的最简单方法是什么?
答案 0 :(得分:1)
尝试更改查询
string sql =“SELECT * FROM GROUPS”;
到下面
string sql = "SELECT GROUP_ID, GROUP_NAME, IsNull(DESCRIPTION, '') as DESCRIPTION FROM GROUPS";
答案 1 :(得分:0)
如果没有自定义序列化程序,我认为您无法达到您想要的效果。 DataTable名称在设计上是唯一的,并且DataSet的序列化尊重该唯一性,因为它们必须是可反序列化的,这意味着序列化后名称必须是唯一的。