为指定的XML文件生成类并反序列化

webservice的那种不说了,vs会自动生成客户端访问的类,

遇到这样一种情况:XML已知,要你处理

以往的经验直接将XML文件读取到dataset里,使用SqlBulkCopy批量导入到数据库完事,参见http://www.cnblogs.com/kkun/archive/2009/08/18/1548760.html

读取到DataSet里后发现不成,XML是多级的,根,子节点,子子节点,子子子节点,这样的树形数据DataSet处理不了,默认只取子节点,实际数据在子子节点或子子子节点

换思路吧,此路不通

使用程序解析,太Easy了,直接使用XPath语法取出Node集合即可,但除了此方法外是否还有其它方法呢?为了借助SqlBulkCopy的优势,

这种方法的好处显而易见,简单,不好的地方就是需要把Node数据导入到DataTable里,这里铁定有拆装箱的效率问题

想办法最高效得到DataRow[]或DataTable,最终找到另外一种办法解决!虽然效率同上述方法差不多,避免不了的拆装箱,好处是:多了一个选择,废话太多了,来看如何做到标题所述的办法

 

1,已知XML文件,格式如下

<?xml version="1.0" encoding="utf-8" ?>
<Person>
  <Name>KornZhang</Name>
  <Age>26</Age>
</Person>

 

2,根据此XML文件生成其架构(Schema)

打开VS命令行工具

image

假如我的文件位于D:\XMLFile1.xml

在命令行窗口里输入:XSD D:\XMLFile1.xml

image

我们的XML架构生成了,位于如图所示文件夹中(C:\Program Files\Microsoft Visual Studio 9.0\VC\xmlfile1.xsd)

将其Copy到D盘根目录下,输入命令:XSD D:\xmlfile1.xsd /c

image

该类生成了!位于如图所示位置(C:\Program Files\Microsoft Visual Studio 9.0\VC\xmlfile1.cs)

3,将此类添加至项目中

写反序列化函数

public Person DeSerialize( string file ) {
    Person Person;
    using( FileStream fs = new FileStream( file, FileMode.Open ) ) {
        XmlSerializer formatter = new XmlSerializer( typeof( Person ) );
        Person = (Person)formatter.Deserialize( fs );
    }
    return Person;
}

稍加修改,改为泛型类,代码如下(不是必须的):

public T DeSerialize<T>( string file ) {
    T t;
    using( FileStream fs = new FileStream( file, FileMode.Open ) ) {
        XmlSerializer formatter = new XmlSerializer( typeof( T ) );
        t = (T)formatter.Deserialize( fs );
    }
    return t;
}

 

 

 

试下返回序列化功能!

image

总结下:
一开始我只知道有个XML文件,要在C#中处理,入库也好,绑定也好,总之这个文件需要处理才能使用,
处理方式有很多,解析XML是第一理想办法,但它解析出来的是一堆零星的局部变量;
最后我们借助工具实现该XML的实体类,并借助返序列化函数将其高效的解析到了内存中,往下的处理就入俗了,不再关心;

-----------------------------------------------------
补充:上面说的方法使用XPath得到node集合,node.InnerText清一色都是string类型,可明明知道xml中的Age节点表示年龄
自然是int类型,这样node集合则需要类型转换,拆装箱!然后本文所说的方法最后也需要拆装箱,因为默认的生成的CS文件里,Person类中Age字段也是string类型,
如将其修改为int类型,那反序列化函数岂不是
有点乱,整理下:原始数据int类型,取的时候却要转换,因node.InnerText为string类型
使用反序列化,将生成的CS中Person类的定义稍加修改,将Age改为int类型,也可以反序列化成功,此时实体Age直接就是int类型,避免了上一步的拆装箱步骤
也不是避免了,只是反序列化函数帮我们直接拆装箱为int类型了,不必再次拆装箱操作,省了一步操作
还是不甚清楚,再次整理!
第一种方法:int -> node.InnerText -> int
本文方法:int -> 反序列化string ->
改进方法:int -> 反序列化int -> int
这样的话,确实效率有所提高,把拆装箱的工作交给反序列化函数,对于它来讲,反序列化为string和int类型,是没有区别的
-----------------------------------------------------
记录学习中的点点滴滴,记录这一路走来的风景
文章来自http://cnblogs.com/kkun,转载请注明出处



posted @ 2020-12-11 10:42  沙耶  阅读(226)  评论(0编辑  收藏  举报