映射xml订单
假定你在编写一个接受用户订单的应用程序,订单是xml格式的,它的XSD大纲如图1定义。该大纲定义了三种复合类型,分别提供订单的客户数据、订单数据和线性数据项。一个顶层Customer元素定义了xml文档的根。这个封闭的系统定义了元素之间的关系:Order元素包含了一个LineItem元素,Customer元素包含一个Order元素。图2显示了符合图1定义的大纲的一个xml文档实例。
图1:XSD大纲
<?xml version="1.0" encoding="utf-8"?> <xs:schema targetNamespace="urn:Sep2003Example" elementFormDefault="qualified" xmlns="urn:Sep2003Example" xmlns:xs="http://www.w3.org/2001/xmlSchema"> <xs:complexType name="OrderType"> <xs:sequence> <xs:element name="OrderID" type="xs:integer" /> <xs:element name="LineItem" type="LineItemType" /> </xs:sequence> </xs:complexType> <xs:complexType name="LineItemType"> <xs:sequence> <xs:element name="ProductID" type="xs:int" /> <xs:element name="Quantity" type="xs:int" /> <xs:element name="UnitPrice" type="xs:decimal" /> </xs:sequence> </xs:complexType> <xs:complexType name="CustomerType"> <xs:sequence> <xs:element name="CustomerID" type="xs:string" /> <xs:element name="Order" type="OrderType" /> </xs:sequence> </xs:complexType> <xs:element name="Customer" type="CustomerType"> </xs:element> </xs:schema>
<?xml version="1.0" ?> <Customer xmlns="urn:Sep2003Example"> <CustomerID>ALFKI</CustomerID> <PO>9572658</PO> <Address> <Street>One Main Street</Street> <City>Anywhere</City> <State>NJ</State> <Zip>08080</Zip> </Address> <Order> <OrderID>10966</OrderID> <LineItem> <ProductID>37</ProductID> <UnitPrice>26.50</UnitPrice> <Quantity>8</Quantity> <Description>Gravad lax</Description> </LineItem> <LineItem> <ProductID>56</ProductID> <UnitPrice>38.00</UnitPrice> <Quantity>12</Quantity> <Description>Gnocchi di nonna Alice</Description> </LineItem> </Order> </Customer>
using System; using System.Collections; using System.Data; using System.Data.SqlClient; using System.xml; public class xmlMap { public static void Main() { // 建立数据集和读取大纲 DataSet orderDS = new DataSet("CustOrder"); orderDS.ReadxmlSchema("CustOrderLitem.xsd"); // 打印数据集的形式 printDSShape(orderDS); // 把一个xml格式的订单读入数据集 orderDS.Readxml("Order.xml",System.Data.xmlReadMode.IgnoreSchema); // 打印数据集中的数据 printDSData(orderDS); // 此处插入业务规则和数据库更新逻辑 } private static void printDSShape(DataSet ds) { foreach (DataTable dt in ds.Tables) { Console.WriteLine("",dt.TableName); // 打印列的名称和类型 foreach (DataColumn dc in dt.Columns) Console.WriteLine("tt",dc.ColumnName,dc.DataType.ToString()); } } private static void printDSData(DataSet ds) { foreach (DataTable dt in ds.Tables) { Console.WriteLine("n:", dt.TableName); // 打印列的头 foreach (DataColumn dc in dt.Columns) Console.Write("t",dc.ColumnName); Console.WriteLine(""); // 输出数据 foreach (DataRow dr in dt.Rows) { foreach(DataColumn dc in dt.Columns) System.Console.Write("t",dr[dc]); System.Console.WriteLine(""); } } } }
Customer CustomerID System.String Customer_Id System.Int32 Order OrderID System.Int64 Order_Id System.Int32 Customer_Id System.Int32 LineItem ProductID System.Int32 Quantity System.Int32 UnitPrice System.Decimal Order_Id System.Int32 Customer: CustomerID Customer_Id ALFKI 0 Order: OrderID Order_Id Customer_Id 10966 0 0 LineItem: ProductID Quantity UnitPrice Order_Id 37 8 26.5 0 56 12 38 0
把大纲载入数据集之后,为了完成关系映射,你需要做的所有事情就是把xml数据载入该数据集。列表1的Readxml方法打开叫作Order.xml的文件,该文件如图2所示。接着,它把文件中的数据读取到你刚才读取大纲建立的数据集中的数据表里。你的xml订单现在可以通过数据集访问了。
为了演示如何访问数据集中的数据,列表1的printDSData方法在数据表中导航,对于每张表,都显示列的名称,紧接着显示这张表的所有的行。图3显示为ReadxmlSchema方法给数据集添加的Customer_Id和Order_Id列自动生成了值。
请注意,Order.xml出现的三个元素--PO、Address和Description--没有映射到数据表中。这些数据被忽略了,因为你提供给数据集的大纲没有包含这些元素,当数据集建立关系数据缓存的外形并载入xml数据的时候,它简单地忽略了没有在大纲中描述的数据。即使在你从客户那儿接收到的xml订单中包含了没有预料到的额外数据,这种简便特性也可以让你的代码正常地工作。
建立使用数据缓存的应用程序
现在你已经知道如何使用数据集为xml数据建立关系数据缓存了,你可以应用这种技术来实现一个执行业务逻辑并更新SQL Server的应用程序。当你使用数据集编程模型的时候实现业务逻辑相对直接。ADO.NET为你提供了更新SQL Server中数据的几种选择,包括使用数据适配器、编写自己的查询,以及执行存储过程。数据集使把xml数据映射成关系模型很容易,剩余的事情是你的了。