在C#开发中,DataTable是常用的内存数据表结构,而XML是通用的数据交换格式,将DataTable转换为XML是很多业务场景下的常见需求,比如需要将临时存储的数据导出为通用格式,或者传递给其他支持XML的系统使用。

方法一:使用DataTable内置的WriteXml方法
DataTable类本身提供了WriteXml方法,可以直接将表中的数据写入到XML流或者文件中,这是最简便的转换方式,不需要手动处理XML节点结构。
基本使用步骤
首先创建DataTable并添加测试数据,然后调用WriteXml方法将内容输出到字符串或者文件,以下是完整的代码示例:
using System;
using System.Data;
using System.IO;
using System.Text;
namespace DataTableToXmlDemo
{
class Program
{
static void Main(string[] args)
{
// 创建DataTable并添加列
DataTable dt = new DataTable("UserTable");
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
// 添加测试数据行
dt.Rows.Add(1, "张三", 25);
dt.Rows.Add(2, "李四", 30);
dt.Rows.Add(3, "王五", 28);
// 使用StringWriter将XML内容输出到字符串
using (StringWriter sw = new StringWriter())
{
// 调用WriteXml方法写入数据
dt.WriteXml(sw);
string xmlContent = sw.ToString();
Console.WriteLine("转换后的XML内容:");
Console.WriteLine(xmlContent);
}
// 也可以直接写入到本地文件
string filePath = "user_data.xml";
dt.WriteXml(filePath);
Console.WriteLine($"XML文件已保存到:{filePath}");
}
}
}
方法注意事项
- 默认生成的XML会包含DataTable的名称作为根节点,每一行数据对应一个子节点,列名作为子节点的元素名。
- 如果需要自定义XML的节点结构,可以通过修改DataTable的
TableName属性调整根节点名称,或者修改列名调整子元素名称。 - 该方法会自动处理特殊字符的转义,不需要开发者手动处理内容中的特殊符号。
方法二:手动构建XmlDocument实现转换
如果需要对生成的XML结构有更精细的控制,比如添加自定义属性、调整节点层级,可以选择手动构建XmlDocument对象的方式实现转换。
实现步骤
首先创建XmlDocument对象,然后遍历DataTable的列和行,手动创建对应的XML节点,最后输出XML内容,以下是代码示例:
using System;
using System.Data;
using System.Xml;
namespace DataTableToXmlDemo
{
class Program
{
static void Main(string[] args)
{
// 创建测试DataTable
DataTable dt = new DataTable("ProductTable");
dt.Columns.Add("ProductId", typeof(int));
dt.Columns.Add("ProductName", typeof(string));
dt.Columns.Add("Price", typeof(decimal));
dt.Rows.Add(101, "笔记本电脑", 4999.00m);
dt.Rows.Add(102, "无线鼠标", 89.90m);
dt.Rows.Add(103, "机械键盘", 299.00m);
// 创建XmlDocument对象
XmlDocument xmlDoc = new XmlDocument();
// 创建XML声明节点
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
xmlDoc.AppendChild(xmlDeclaration);
// 创建根节点
XmlElement rootElement = xmlDoc.CreateElement("Products");
xmlDoc.AppendChild(rootElement);
// 遍历DataTable的每一行
foreach (DataRow row in dt.Rows)
{
// 创建行对应的节点,添加自定义属性
XmlElement productElement = xmlDoc.CreateElement("Product");
productElement.SetAttribute("Id", row["ProductId"].ToString());
// 遍历每一列,创建子元素
foreach (DataColumn col in dt.Columns)
{
XmlElement colElement = xmlDoc.CreateElement(col.ColumnName);
colElement.InnerText = row[col].ToString();
productElement.AppendChild(colElement);
}
rootElement.AppendChild(productElement);
}
// 输出XML内容
string xmlResult = xmlDoc.OuterXml;
Console.WriteLine("手动构建的XML内容:");
Console.WriteLine(xmlResult);
// 保存到文件
xmlDoc.Save("product_data.xml");
Console.WriteLine("自定义XML文件保存完成");
}
}
}
两种方法的适用场景对比
| 转换方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| WriteXml内置方法 | 代码简洁,无需手动处理节点,自动处理特殊字符 | XML结构固定,自定义程度低 | 对XML结构无特殊要求,快速实现转换的场景 |
| 手动构建XmlDocument | 可完全自定义XML结构、节点属性、层级关系 | 代码量较多,需要手动处理节点创建和遍历 | 需要符合特定XML schema,或者有特殊结构要求的场景 |
常见问题说明
在转换过程中,如果DataTable中包含null值,使用WriteXml方法时会自动将null值对应的节点设置为空内容,而手动构建时需要注意判断null值,避免出现空引用异常。
注意:如果DataTable中包含二进制类型的数据,转换为XML时可能会被编码为Base64字符串,接收方需要对应解码才能还原原始数据。
实际开发中可以根据业务需求选择合适的转换方式,大部分常规场景使用内置的WriteXml方法即可满足需求,需要自定义结构时再选择手动构建的方式。