新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → 使用.NET存储XML数据 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 12306 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 使用.NET存储XML数据 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     admin 帅哥哟,离线,有人找我吗?
      
      
      
      威望:9
      头衔:W3China站长
      等级:计算机硕士学位(管理员)
      文章:5255
      积分:18406
      门派:W3CHINA.ORG
      注册:2003/10/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给admin发送一个短消息 把admin加入好友 查看admin的个人资料 搜索admin在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给admin  访问admin的主页 引用回复这个贴子 回复这个贴子 查看admin的博客楼主
    发贴心情 使用.NET存储XML数据

    SQL Server 2000和XML for SQL Server 2000 Web版本(SQLXML)提供了三种存储XML数据的途径:XML Bulk Load和Updategrams,这两种客户端技术使用带有注解的大纲指定XML文档内容和数据库的表之间的映射;OpenXML是一种服务器端技术,它允许你在XML文档上定义关系视图,有了OpenXML的关系视图,你就能使用T-SQL代码查询XML文档中的数据并把结果存储在你的SQL Server数据库中。

      这三种技术中的每一种都是为特定的目的设计的。XML Bulk Load把来自很大的XML文档的数据存储在SQL Server中;Updategrams执行SQL Server数据的优化更新(优化更新是没有锁(lock)的更新,在这种更新中系统检测是否有其它用户在原来读取数据后改变了它);OpenXML提供了人们熟悉的XML数据关系访问方法。

      在这三种技术中,OpenXML是最灵活的,因为它提供了一个编程模型(T-SQL),在把XML数据存储在SQL Server数据库之前,你可以使用这种编程模型在XML数据上编写业务规则或执行计算逻辑。但是,由于OpenXML是一种基于服务器的技术,如果你频繁的使用它或者有大量的文档,它会降低SQL Server的性能。不过,如果你采用了微软.NET框架组件,你就可以使用ADO.NET的数据集绕开这些性能和可伸缩性方面的限制,ADO.NET数据集赋予你一个强大的技术--为把XML数据存储在SQL Server包含了一个完整的编程模型。

      数据集、数据表和XML映射

      你可以使用数据集简单地从SQL Server中生成XML查询结果。通过提供一种可以在客户端和中间层计算机上使用的关系数据缓存(cache),数据集能够载入和维护多种数据源(包括SQL Server、其它的关系型数据库和XML)中的数据。

      当你从XML文档中载入一个数据集的时候,该数据集必须把存储在层次XML表现(representation)中的数据映射成数据集的关系表现。例如,如果你的XML文档包含一个Order元素列表,而它又有一个作为子元素的嵌套的LineItem元素,那么通常这个文档被映射成关系表现中的Orders和LineItems数据表。这种映射的目的与OpenXML使用Xpath查询构造XML文档上的关系视图的方法的目的是一样的。但是与使用Xpath规范不同,数据集有自己的映射数据的方式。

      数据集使用XML大纲定义(XSD)大纲把数据从XML文档映射到数据集的关系数据缓存中。数据集为你提供了指定映射XML数据的大纲的两种方法。首先,你可以引用一个定义了XML文档中使用的元素,属性和关系的XSD大纲。另一种方法是,你可以直接从文档的结构中推理大纲。换句话说,数据集可以通过检查XML文档的结构和内容建立大纲。

      当你引用XSD大纲的时候,数据集使用这个大纲中定义的元素、属性与元素之间的关系来构造关系数据缓存中的数据表、数据列和数据关系,你可以使用这个数据缓存存储被映射的XML数据。我谈到关系数据缓存中的结构或大纲的时候,一般把它称为数据缓存的形式。当数据集处理大纲的时候,它会应用一组规则,这种规则与映射大纲中没有指定注解时Updategrams 和XML Bulk Load使用的默认映射规则相似,数据集使用这种规则建立数据集用于存储被映射的XML数据的表。数据集的映射规则概述如下:

      · 复合元素--即包含其它元素或属性的元素--被映射成表。

      · 属性和简单值(simple-valued)子元素--只包含数据,不包含其它元素或属性的元素--被映射成列。

      · 数据类型从XSD类型映射为.NET类型。 

      推理(Inference)是一种快速、方便的把XML文档载入数据集的方法。表、列和关系都是"自我测量"(introspection)自动建立的,"自我测量"是数据集检查XML文档的结构和内容的过程。尽管使用推理明显减少了你的编程负担,但是它也给你的实现带来了不可预测性,因为对XML文档的很小的改动可能引起数据集建立不同形式的表。这些形式的改变可能引起你的应用程序意外中断。因此,我推荐你一般为应用程序引用一个大纲,建立原型的时候限制推理的使用。

      现在让我们看一看如何使用大纲建立一个可用于更新SQL Server数据库的客户端数据集数据缓存的例子。

    映射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>

      图2:一个XML文档示例

    <?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>

      列表1中显示的C#代码使用ReadXmlSchema方法把图1中的大纲载入一个叫作orderDS的数据集中。ReadXmlSchema建立了三个数据表,它们分别与大纲中定义的Customer、Order和LineItem元素对应。因此你可以验证这个大纲在关系数据缓存中建立了预期的表,printDSShape方法把每个表的名称写到控制台上,后面跟着列的列表和每列的数据类型。

      列表1: 建立关系数据缓存的C#代码

    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("{0}",dt.TableName);

    // 打印列的名称和类型
    foreach (DataColumn dc in dt.Columns)
    Console.WriteLine("\t{0}\t{1}",dc.ColumnName,dc.DataType.ToString());
    }
    }

    private static void printDSData(DataSet ds)
    {
    foreach (DataTable dt in ds.Tables)
    {
    Console.WriteLine("\n{0}:", dt.TableName);

    // 打印列的头
    foreach (DataColumn dc in dt.Columns)
    Console.Write("{0}\t",dc.ColumnName);
    Console.WriteLine("");

    // 输出数据
    foreach (DataRow dr in dt.Rows)
    {
    foreach(DataColumn dc in dt.Columns)
    System.Console.Write("{0}\t",dr[dc]);
    System.Console.WriteLine("");
    }
    }
    }
    }

      仔细查看一下列的名称。尽管大纲中没有指定Customer_Id和Order_Id列,但是它们还是出现在数据表中。ReadXmlSchema给数据集自动添加这些列。数据集把这些列用作外部键(foreign key),以模拟Customer元素与它的Order元素之间、Order元素与它的LineItem元素之间的关系。因为典型情况下XML使用嵌套的关系代替了外部键,所以数据集自动生成自己的主键、数据表之间的外部键,并把它们存储在这些列中。

      请同时仔细查看图3中的数据类型--数据集已经把来自XML大纲数据类型的数据类型映射为对应的.NET数据类型。当你把XML文档载入数据集的时候,该数据集把来自XML的每一个值转换为对应的.NET类型。

      图3:生成的数据类型和记录

    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数据映射成关系模型很容易,剩余的事情是你的了。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------

    -----------------------------------------------

    第十二章第一节《用ROR创建面向资源的服务》
    第十二章第二节《用Restlet创建面向资源的服务》
    第三章《REST式服务有什么不同》
    InfoQ SOA首席编辑胡键评《RESTful Web Services中文版》
    [InfoQ文章]解答有关REST的十点疑惑

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/6/23 11:56:00
     
     brillant 帅哥哟,离线,有人找我吗?
      
      
      等级:大一(高数修炼中)
      文章:11
      积分:115
      门派:XML.ORG.CN
      注册:2004/6/24

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给brillant发送一个短消息 把brillant加入好友 查看brillant的个人资料 搜索brillant在『 Dot NET,C#,ASP,VB 』的所有贴子 引用回复这个贴子 回复这个贴子 查看brillant的博客2
    发贴心情 
    这可是新技术
    我现在就干这。。。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/6/24 18:01:00
     
     yangjinhui 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:10
      积分:99
      门派:XML.ORG.CN
      注册:2004/6/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给yangjinhui发送一个短消息 把yangjinhui加入好友 查看yangjinhui的个人资料 搜索yangjinhui在『 Dot NET,C#,ASP,VB 』的所有贴子 引用回复这个贴子 回复这个贴子 查看yangjinhui的博客3
    发贴心情 
    你好,我是刚刚看到这项技术,看上还有些不懂。
    不知道怎样在联系
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/6/25 15:59:00
     
     xmzhy 帅哥哟,离线,有人找我吗?狮子座1978-8-18
      
      
      威望:5
      等级:计算机学士学位
      文章:385
      积分:2003
      门派:XML.ORG.CN
      注册:2003/10/22

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给xmzhy发送一个短消息 把xmzhy加入好友 查看xmzhy的个人资料 搜索xmzhy在『 Dot NET,C#,ASP,VB 』的所有贴子 引用回复这个贴子 回复这个贴子 查看xmzhy的博客4
    发贴心情 
    能否提供一个范例,谢谢!xmzhy@21cn.com
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/12/1 16:40:00
     
     GoogleAdSense狮子座1978-8-18
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/4/18 10:32:06

    本主题贴数4,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    89.844ms