现在有一个XML文档,准备把它转换为ADO.NET的DataSet。这样就可以把XML加载到数据库中,或者把数据绑定到.NET数据控件上,例如DataGrid。此时可以把XML文档用作数据库,完全消除数据库的系统开销。如果数据比较少,这是完全有可能的。看看下面这些代码(位于ADOSample5中):
private void button1_Click(object sender, System.EventArgs e)
{
//create a new DataSet
DataSet ds=new DataSet("XMLProducts");
//read in the XML document to the Dataset
ds.ReadXml("..\\..\\..\\prod.xml");
//load data into grid
dataGrid1.DataSource=ds;
dataGrid1.DataMember="products";
//create the new XmlDataDocument
doc=new XmlDataDocument(ds);
//load the product names into the listbox
XmlNodeList nodeLst=doc.SelectNodes("//ProductName");
foreach(XmlNode nd in nodeLst)
listBox1.Items.Add(nd.InnerXml);
}
这很简单。实例化一个新DataSet对象,调用ReadXml方法,把XML放在DataSet的一个DataTable中。与WriteXml方法一样,ReadXml的参数是XmlReadMode。ReadXml还可以使用XmlReadMode中的更多选项(如表23-9所示)。
表 23-9
选 项 |
说 明 |
Auto |
把XmlReadMode设置为最合适的值。如果数据是DiffGram格式,就选择DiffGram;如果已经读取了模式,或者检测到某个内联模式,就选择ReadSchema。如果没有为DataSet指定模式,也没有检测到内联模式,就选择IgnoreSchema |
DiffGram |
读取DiffGram,把变化应用到DataSet上。本章的后面介绍 DiffGrams |
Fragment |
读取包含XDR模式片断的文档,例如SQL Server创建的类型 |
选 项 |
说 明 |
IgnoreSchema |
忽略任何找到的内联模式,把数据读入当前的DataSet模式中,如果数据与DataSet模式不匹配,就删除它 |
InferSchema |
忽略任何内联模式,根据XML文档中的数据创建模式。如果DataSet中已经有一个模式,就使用该模式,如果需要,可以用其他列或表格来扩展它。如果存在一个列,但其数据类型不符,就会抛出一个异常 |
ReadSchema |
读取内联模式,加载数据。不重写DataSet中的模式,但如果内联模式中的表已经存在于DataSet中,就抛出一个异常 |
这里也有ReadSchema方法,它读取独立的模式,创建相应的表、列和关系。如果模式和数据都不在内联中,就可以使用ReadSchema方法。该方法也有4个重载方法:其参数分别是带有文件和路径名的字符串、基于Stream的对象、基于TextReader的对象和基于XmlReader的对象。
要说明如何正确地创建数据表,加载包含前面示例中使用的Products和Suppliers表的XML文档。但这次加载的列表框中包含DataTable名、DataColumn名和数据类型。可以把它与最初的Northwind数据库比较一下,看看这些内容是否有改变。下面是我们使用的代码,包含在ADOSample5中:
private void button1_Click(object sender, System.EventArgs e)
{
//create the DataSet
DataSet ds=new DataSet("XMLProducts");
//read in the XML document
ds.ReadXml("..\\..\\..\\SuppProd.xml");
//load data into grid
dataGrid1.DataSource=ds;
dataGrid1.DataMember="products";
//load the listbox with table, column and datatype info
foreach(DataTable dt in ds.Tables)
{
listBox1.Items.Add(dt.TableName);
foreach(DataColumn col in dt.Columns)
{
listBox1.Items.Add(
'\t' + col.ColumnName + " - " + col.DataType.FullName);
}
}
}
注意添加了两个foreach循环。第一个循环从DataSet的表集合中获得每个表的名称,在内层的foreach循环中,获得DataTable中每一列的名称和数据类型。把这些数据加载到列表框中,显示它们。图23-11是执行这段代码后所得的屏幕图。
图 23-11
从列表框中可以看出,DataTables中包含的列都有正确的名称和数据类型。
还要注意,最后的两个示例都没有在数据库中传入或传出任何数据,所以没有定义SqlDataAdapters 或SqlConnections。这说明了System.Xml 命名空间和ADO.NET的灵活性。可以用多种格式查看相同的数据。如果需要进行转换,以HTML格式显示数据,或者需要把数据绑定到网格上,就应获取这些数据,用一个方法调用,把它们以需要的格式显示出来。
更多DotNet好文章www.zdexe.com