XML与DataSet的相互转换类

 XmlDatasetConvert 该类提供了四种方法:
1、将xml对象内容字符串转换为DataSet
2、将xml文件转换为DataSet
3、将DataSet转换为xml对象字符串
4、将DataSet转换为xml文件

XmlDatasetConvert.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Xml;

namespace XmlDesign
{
    class XmlDatasetConvert
    {
        //将xml对象内容字符串转换为DataSet
        public static DataSet ConvertXMLToDataSet(string xmlData)
        {
            StringReader stream = null;
            XmlTextReader reader = null;
            try
            {
                DataSet xmlDS = new DataSet();
                stream = new StringReader(xmlData);
                //从stream装载到XmlTextReader
                reader = new XmlTextReader(stream);
                xmlDS.ReadXml(reader);
                return xmlDS;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null) reader.Close();
            }
        }

        //将xml文件转换为DataSet
        public static DataSet ConvertXMLFileToDataSet(string xmlFile)
        {
            StringReader stream = null;
            XmlTextReader reader = null;
            try
            {
                XmlDocument xmld = new XmlDocument();
                xmld.Load(xmlFile);

                DataSet xmlDS = new DataSet();
                stream = new StringReader(xmld.InnerXml);
                //从stream装载到XmlTextReader
                reader = new XmlTextReader(stream);
                xmlDS.ReadXml(reader);
                //xmlDS.ReadXml(xmlFile);
                return xmlDS;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null) reader.Close();
            }
        }

        //将DataSet转换为xml对象字符串
        public static string ConvertDataSetToXML(DataSet xmlDS)
        {
            MemoryStream stream = null;
            XmlTextWriter writer = null;

            try
            {
                stream = new MemoryStream();
                //从stream装载到XmlTextReader
                writer = new XmlTextWriter(stream, Encoding.Unicode);

                //用WriteXml方法写入文件.
                xmlDS.WriteXml(writer);
                int count = (int)stream.Length;
                byte[] arr = new byte[count];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(arr, 0, count);

                UnicodeEncoding utf = new UnicodeEncoding();
                return utf.GetString(arr).Trim();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (writer != null) writer.Close();
            }
        }

        //将DataSet转换为xml文件
        public static void ConvertDataSetToXMLFile(DataSet xmlDS,string xmlFile)
        {
            MemoryStream stream = null;
            XmlTextWriter writer = null;

            try
            {
                stream = new MemoryStream();
                //从stream装载到XmlTextReader
                writer = new XmlTextWriter(stream, Encoding.Unicode);

                //用WriteXml方法写入文件.
                xmlDS.WriteXml(writer);
                int count = (int)stream.Length;
                byte[] arr = new byte[count];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(arr, 0, count);

                //返回Unicode编码的文本
                UnicodeEncoding utf = new UnicodeEncoding();
                StreamWriter sw = new StreamWriter(xmlFile);
                sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                sw.WriteLine(utf.GetString(arr).Trim());
                sw.Close();
            }
            catch( System.Exception ex )
            {
                throw ex;
            }
            finally
            {
                if (writer != null) writer.Close();
            }
        }

    }
}

使用示例
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data;

namespace XmlDesign
{
    class Program
    {
        static void Main(string[] args)
        {
            DataSet ds = new DataSet();

            转换一个XML文件(本地\网络均可)为一个DataSet#region 转换一个XML文件(本地\网络均可)为一个DataSet
            //http://news.baidu.com/n?cmd=1&class=sportnews&tn=rss
            //F:\study\001CSharp_Study\002Source\XmlDesign\XmlDesign\Save_Plan.xml
            ds = XmlDatasetConvert.ConvertXMLFileToDataSet(@"http://news.baidu.com/n?cmd=1&class=sportnews&tn=rss");
            Console.WriteLine("数据集名为\"{0}\",包含{1}个表", ds.DataSetName, ds.Tables.Count);
            foreach(DataTable dt in ds.Tables)
            {
                PrintTableName(dt.TableName);
            };
            #endregion

            构造一个DataSet,并转换为XML字符串#region 构造一个DataSet,并转换为XML字符串
            DataSet ds1 = new DataSet();
            DataTable dt1 = new DataTable();
            dt1.TableName = "test";
            dt1.Columns.Add("id");
            dt1.Columns.Add("name");
            dt1.Rows.Add("i001", "hekui");
            dt1.Rows.Add("i002", "liyang");

            DataTable dt2 = new DataTable();
            dt2.TableName = "test1";
            dt2.Columns.Add("bookid");
            dt2.Columns.Add("bookname");
            dt2.Rows.Add("b001", "书本1");
            dt2.Rows.Add("b002", "书本2");

            ds1.Tables.Add(dt1);
            ds1.Tables.Add(dt2);
            ds1.DataSetName = "方案";
            string xmlOut = XmlDatasetConvert.ConvertDataSetToXML(ds1);
            #endregion

            转换一个XML字符串为一个DataSet#region 转换一个XML字符串为一个DataSet
            DataSet ds2 = new DataSet();
            ds2 = XmlDatasetConvert.ConvertXMLToDataSet(xmlOut);
            Console.WriteLine("数据集名为\"{0}\",包含{1}个表", ds2.DataSetName, ds2.Tables.Count);
            foreach (DataTable dt in ds2.Tables)
            {
                PrintTableName(dt.TableName);
            };
            #endregion

            转换一个Dataset为一个XML文件#region 转换一个Dataset为一个XML文件
            XmlDatasetConvert.ConvertDataSetToXMLFile(ds2, "c:\\adadsda1.xml");
            #endregion
           
            Console.ReadLine();
        }

        private static void PrintTableName(string tableName)
        {
            Console.WriteLine(tableName);
        }
    }
}


 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1833187

 

===============================================================

XML与DataSet的互转

XML与DataSet进行交互是非常容易的,无论是XML文件还是XML字符串。而我们现在主要用的都是XML字符串的方式。即使用DataSet.GetXml()方式。

        一般来说,用DataSet生成的Xml格式应该是如下方式:

<NewDataSet>

    <Table>

        <Columns1>……</Columns1>

        <Columns2>……</Columns2>

    </Table>

    <Table>

        <Columns1>……</Columns1>

        <Columns2>……</Columns2>

 

    </Table>

    <Table1>

        ……

    </Table1>

</NewDataSet>

        上面是一个基本的格式的由DataSet转成的XML,其并不包含Schema。在VS.net的开发中,无论你是绑定XML,还是DataSet,效果都是一样的。

        现在我来解释一下DataSet生成XML的格式:

        应该可以看到,首先是根结点:<NewDataSet />  这个应该不用多说,再其下我们可以看到<Table />、<Table1 />等等这样的子结点。当在DataSet中只有一个表的时候,在XML中只会有<Table>结点,而当DataSet中有多个表的时候,在XML中会将这些Tabel表示出来,第1个表为<Table />,第2个表为<Table1 />,第3个表为<Table2 />…………。而且如何在一个表中具有多行的时候,每一行都会放到一个<Table />结点中。假如我们有一个表中有两个字段:ID与NAME,则按上述示例,在XML中的表示为:

<NewDataSet>

    <Table>

        <ID>ID1</ID>

        <NAME>NAME1</NAME>

    </Table>

    <Table>

        <ID>ID2</ID>

        <NAME>NAME2</NAME>

 

    </Table>

</NewDataSet>

        但是如果你足够细心去留意这些的话,就会发现,当在数据表中的某个字段为空值(即为null,而并非为”")时,其根本不会显示在XML上,这就造成了当需要对XML进行数据绑定的时候,根本无法找到该字段。而且我们也会发现,无论我们在数据库中存放的表是什么名字,在XML的显示中一律依次用<Table />、<Table1 />来代替,我们仅仅知道在每个表中的字段名称而已。还有第3点,在XML中所有的数据都是String类型的,不管是数字还是时间。这又该怎么办呢?

        当然,这就要归功于XmlSchema的功劳了。我将会在明天将第2部分–“Schema的作用”写出来。

上面提到了几个问题:
    1、当在数据表中的某个字段为空值(即为null,而并非为”")时,其根本不会显示在XML上,这就造成了当需要对XML进行数据绑定的时候,根本无法找到该字段。该如何解决?
    2、无论我们在数据库中存放的表是什么名字,在XML的显示中一律依次用<Table />、<Table1 />来代替,如何通过表名称来找呢?
    3、在XML中所有的数据都是String类型的,不管是数字还是时间。如何让Xml中的数据类型与DataSet中的一样?

    好,现在开始讲解Schema。我们可以通过DataSet.GetXmlSchema()来得到DataSet的Schema。当然,该方法还是用来生成String这符串的。我们首先来看一下它的格式。
    假如有如下表:
表Test,其字段描述如下:
ID(string) Name(string) time(DateTime)
1  aa  2004-5-1
2  bb  

其DataSet的Xml格式如下:
<?xml version=”1.0″ encoding=”utf-16″?>
<xs:schema id=”NewDataSet” xmlns=”" xmlns:xs=”http://www.w3.org/2001/XMLSchema” xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata”>
  <xs:element name=”NewDataSet” msdata:IsDataSet=”true” msdata:Locale=”zh-CN”>
    <xs:complexType>
      <xs:choice maxOccurs=”unbounded”>
        <xs:element name=”test”>
          <xs:complexType>
            <xs:sequence>
              <xs:element name=”ID” type=”xs:string” minOccurs=”0″ />
              <xs:element name=”Name” type=”xs:string” minOccurs=”0″ />
              <xs:element name=”time” type=”xs:dateTime” minOccurs=”0″ />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

    至于Schema的写法,我就不多说了,不清楚的朋友可以找一本Xml的基础资料来看一下。这里我们重点要看红色标注的一行,里属性type就是用来表示在Xml中该字段的数据类型。其它属性还包含字段的限制等等。实际上,XmlSchema的作用就在于此。同时,即便在Xml中字段为空时不显示,通过XmlSchema也可以得到完整的数据字段。还有一点,就是表名,你同时也可以看到在XmlSchema中有与Xml中对应的表名,这里看到的为test。
    好,讲到这里,我想你已经大概了解DataSet转为Xml的一些基础知识了。那么现在我再来讲一下Xml还原成DataSet的方法。
    DataSet已经很好的支持了Xml。这一点我在开发过程中感受得非常深刻。DataSet通过客户端是不能够提取的,因此我先转成Xml,然后通过客户端的MSXML进行DOM解析,真的是非常棒哦。有空你也可以试一下它的强大功能。
    Xml转成DataSet主要用DataSet.ReadXmlSchema()和DataSet.ReadXml()方法。注意这里,我们通过DataSet获取时,如果要获取Schame,那么写一定要先将DataSet.ReadXmlSchema()写在前面,因为DataSet只有首先得到数据架构,才能在架构中添加数据哦(想想建筑师们是怎么设计的吧)!

     如果XML数据是DiffGram,那么就用DiffGram格式推导数据。如果XML文档包含内联架构,那么这个架构就用于确定DataSet对象的子元素的结构。这种行为等于ReadSchema选项。如果没有找到架构,那么就用InferXMLSchema方法从DataSet对象推导架构信息。如果载加载DataSet对象时设置一个明确的XmlReadMode方法,那么就可以改进性能。

       在DataSet.GetXml()方法中,会有第二个参数是用来设置Get方法。里面最有作用的就是DiffGram参数。它可以完整保存DataSet中的信息。加入该参数,你再观察一下DataSet生成的Xml,会发现从获取DataSet到对DataSet的记录操作变更全部都记录在Xml中了,这就是DiffGram的功劳。这样,即便我们把DataSet以Xml的方法传递到任何其它层,都可以进行有效的更新或还原了。

DiffGram格式

        DiffGram是一种XML序列化格式,它包括每一行的原始值和当前值。特别地,它包含带有原始值的行列表以及将所有更改组织在一起的最后一节。每一行都由一个为已标示符,用于两节DiffGram之间跟踪改变。下面的清单描述了DiffGram的结构,其中第一行被删除,第三行被修改并且插入了一个新行:

<diffgr:diffgram>
 <DataSetName>
  <Employees diffgr:id=”Employees1″ msdata:rowOrder=”0″>…</Employees>
  <Employees diffgr:id=”Employees3″ msdata:rowOrder=”2″>…</Employees>
  <Employees diffgr:id=”Employees4″ msdata:rowOrder=”3″ diffgr:hasChanges=”modified”>…</Employees>
  <Employees diffgr:id=”Employees5″ msdata:rowOrder=”4″>…</Employees>
  <Employees diffgr:id=”Employees6″ msdata:rowOrder=”5″>…</Employees>
  <Employees diffgr:id=”Employees7″ msdata:rowOrder=”6″>…</Employees>
  <Employees diffgr:id=”Employees8″ msdata:rowOrder=”7″>…</Employees>
  <Employees diffgr:id=”Employees9″ msdata:rowOrder=”8″>…</Employees>
  <Employees diffgr:id=”Employees10″ msdata:rowOrder=”9″ diffgr:hasChanges=”inserted”>…</Employees>
 </DataSetName>
 <diffgr:before>
  <Employees diffgr:id=”Employees2″ msdata:rowOrder=”1″>…</Employees>
  <Employees diffgr:id=”Employees4″ msdata:rowOrder=”3″>…</Employees>
 </diffgr:before>
</diffgr:diffgram>

<diffgr:diffgram>根节点友两个子节点。第一个是带有其当前内容的DataSet对象,包括新添加的行和修改的行,但是不包括删除的行。这种数据树根据DataSet对象命名。用DataSetName属性的到和设置DataSet对象名。第二个节点是以<diffgr:before>节点为根的树。这个树包含恢复DataSet对象原始状态的足够信息。例如,它仍然包含所有被删除的行和所有被修改行的原始内容。受改变影响的所有列都在<diffgr:before>子树种跟踪。

标示行

diffgr:id属性用于在当前行和原始行之间建立链接。diffgr:hasChanges属性可以很快找到那些纪录被删除、插入或者只是修改。

你可以用另外两个属性来控制所保存的XML格式。第一个是DataColumn对象的ColumnMapping属性,它可以指定WriteXml方法是否隐藏了列,是将列写成一个元素、一个属性还是简单的文本。另一个你应该注意的属性就是DataRelation对象的Nested属性。当我们用WriteXml来写父子关系中子表里的记录时,该属性可以指定这些记录是否是嵌套在相关的父表记录中的。

注意:在试图从一个XML DiffGram创建DataSet对象时,要保证目标DataSet对象有与所读取得DataSet对象有同样的架构。不能将DiffGram装入一个空的新创建的DataSet对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值