Kevin Cheng's Yard

电脑是我的老婆,编程是我的灵魂,代码是我的语言,按键是我在歌唱。
精于斯,乐于斯。
 
 

与我联系

  • 发短消息

搜索

 

常用链接

  • 我的随笔
  • 我的空间
  • 我的短信
  • 我的评论
  • 更多链接
  • 我的参与
  • 我的新闻
  • 最新评论
  • 我的标签

留言簿(10)

  • 给我留言
  • 查看留言

我参与的团队

  • .Net 商业智能(1/393)
  • .NetFramework3.0 & 3.5(WCF,WPF,WF)团队(0/566)

随笔分类

  • 日子(3) (rss)
  • .NET编程语言 (rss)
  • .NET杂项 (4) (rss)
  • .NET组件控件(8) (rss)
  • IT新闻(1) (rss)
  • 代码生成器(1) (rss)
  • 工作流引擎 (rss)
  • 建模与快速开发 (5) (rss)
  • 门户框架Portal (rss)
  • 数据库 (4) (rss)
  • 用户界面方案 (rss)
  • 杂项(1) (rss)

随笔档案

  • 2008年8月 (1)
  • 2008年7月 (1)
  • 2007年12月 (1)
  • 2007年6月 (1)
  • 2007年5月 (1)
  • 2007年3月 (2)
  • 2007年1月 (1)
  • 2006年12月 (1)
  • 2006年11月 (1)
  • 2006年10月 (1)
  • 2006年9月 (1)
  • 2006年8月 (3)
  • 2006年6月 (5)
  • 2006年3月 (2)
  • 2005年12月 (7)

文章分类

  • .NET(1) (rss)

相册

  • 回忆

收藏夹

  • 弓虽贝占 (rss)

Blogs

  • DbToCode
  • RapidTier
  • SmartPersistenceLayer
  • 灵感之源

NET WebSite

  • ASP.NET
  • CodeProject
  • CSDN
  • GoDotNet
  • MSDN
  • SourceForge

Special

  • icsharpcode.com
  • Open License
  • Python

最新评论

  • 1. re: Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • 我在winform里用过,感觉这家伙复杂的过头了,比较慢!web里面没敢用!
  • --梅子黄时雨
  • 2. re: Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • @3楼 这个库里面的控件(包括Web和Win)我基本上都使用过,其它的控件还不算太复杂,参考SDK里面的例子就好。 ◎5楼 web版的UltraGrid是慢得不行,不好用 ◎7楼 你说得不错,Re...
  • --Kevin Cheng
  • 3. re: Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • 在使用中,感觉还可以~
  • --swordzhang
  • 4. re: 整理的 AjaxControlToolkit.chm ,希望对大家有用
  • 感谢楼主
  • --dongshuang_8
  • 5. re: Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • 用www.devexpress.com比这个好多了
  • --123QWE

阅读排行榜

  • 1. ASP.NET AJAX Control Tookit 使用文档(5178)
  • 2. 将ASP.NET用户控件转化为自定义控件(3925)
  • 3. Gentle.NET 使用文档(2824)
  • 4. 用 System.Xml 读写XML 整理文档(2783)
  • 5. XML序列化与反序列化 整理文档(2756)

评论排行榜

  • 1. Gentle.NET 使用文档(26)
  • 2. 发布WebFtp 控件(ASP.NET控件,用以web方式进行文件上下传操作) (19)
  • 3. 爱上语法高亮控件ICSharpCode.TextEditor ~o~(15)
  • 4. 发布Oracle存储过程包c#代码生成工具(CodeRobot)(11)
  • 5. 发布语法加亮控件(SyntaxTextBox)(11)

Powered by: 博客园
模板提供:沪江博客
博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅订阅 | 管理

2008年8月20日

Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
     摘要: UltraGrid 是Infragistics netadvanage 控件库中提供的一个Windows 网格控件,功能强大,完全可以取代VS 中提供的 GridView控件。但不知为何,国内介绍它的文章很少。这玩意功能是相当强大,但其属性设计原理和普通控件不太一样,属性极为复杂,没有手册几乎无法编码。在此我整理了一些资料,权当推广了。本是编程用的参考,文笔随意之处望见谅。kevin cheng ... 阅读全文
posted @ 2008-08-20 12:03 Kevin Cheng 阅读(1362) | 评论 (11) | 编辑
 

2008年7月31日

将 DataTable 转化为 Excel Xml 格式供下载

做网站项目时,常需要将表格转化为 Excel 文件供用户下载,实现方法有很多种。如:

    (1)将DataTable 直接进行 xml 序列化成文本

    (2)将DataTable 转化为 Html table 格式

    (3)将DataTable 转化为 Excel Xml 格式

    (4)使用 Microsoft.Office.Interop.Excel.dll 创建Excel文件,再依次填写单元格数据

 

测试了这些方法,发现第3种简单且稳定,其它几种方法都有这样那样的小麻烦(如乱码和文件权限问题),我不在此一一提供这些方法的实现代码。以下为第3种方法的代码,本文参考了该篇文章:http://www.cnblogs.com/tsoukw/archive/2008/05/30/1210485.html,在此,我用静态函数实现了该功能。希望对大家有用。

 

excel xml 格式如:

 

Code
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook
 xmlns
="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:ss
="urn:schemas-microsoft-com:office:spreadsheet">
 
<Worksheet ss:Name="Sheet1">
  
<Table>
   
<Row>
     
<Cell ss:MergeAcross="1"><Data ss:Type="String">Excel xml</Data></Cell>
   
</Row>
   
<Row>
    
<Cell><Data ss:Type="String">A2</Data></Cell>
    
<Cell><Data ss:Type="Number">0.112</Data></Cell>
   
</Row>
  
</Table>
 
</Worksheet>
</Workbook>

 

以下是生成 excel xml 的源代码:

 

Code
        // datatable -> excel
        public static void ExportExcel(DataTable dt, string fileName, string[] displayColumnNames, string[] displayColumnCaptions)
        {
            Response.ClearContent();
            Response.ContentEncoding 
= System.Text.Encoding.UTF8;
            Response.ContentType 
= "application/vnd.ms-excel; charset=utf-8";
            Response.AddHeader(
"Content-Disposition", "attachment;filename=" + fileName);
            Response.Write(DataTableToExcelTable(dt, displayColumnNames, displayColumnCaptions));
            Response.End();
        }

        
// 将 DataTable 转化为 ExcelXml
        public static string DataTableToExcelTable(DataTable dt, string[] displayColumnNames, string[] displayColumnCaptions)
        {
            
// 表开始
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(
"<?xml version=\"1.0\"?>");
            sb.AppendLine(
"<?mso-application progid=\"Excel.Sheet\"?>");
            sb.AppendLine(
"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
            sb.AppendLine(
" <Worksheet ss:Name=\"Sheet1\">");
            sb.AppendLine(
"  <Table>");

            
//
            
// 输出标题
            
//
            sb.AppendLine("   <Row>");
            
if (displayColumnCaptions != null)
            {
                
// 输出指定列标题
                for (int i = 0; i < displayColumnCaptions.Length; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + displayColumnCaptions[i] + "</Data></Cell>");
            }
            
else if (displayColumnNames != null)
            {
                
// 输出展示列标题
                for (int i = 0; i < displayColumnNames.Length; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + displayColumnNames[i] + "</Data></Cell>");
            }
            
else
            {
                
// 输出所有列标题
                for (int i = 0; i < dt.Columns.Count; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + dt.Columns[i].Caption + "</Data></Cell>");
            }
            sb.AppendLine(
"   </Row>");

            
//
            
// 输出数据
            
//
            if (displayColumnNames != null)
            {
                
// 输出指定列数据
                foreach (DataRow dr in dt.Rows)
                {
                    sb.AppendLine(
"   <Row>");
                    
foreach (string colName in displayColumnNames)
                        sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + dr[colName].ToString() + "</Data></Cell>");
                    sb.AppendLine(
"   </Row>");
                }
            }
            
else
            {
                
//输出所有列数据
                foreach (DataRow dr in dt.Rows)
                {
                    sb.AppendLine(
"   <Row>");
                    Object[] ary 
= dr.ItemArray;
                    
for (int i = 0; i <= ary.GetUpperBound(0); i++)
                        sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + ary[i].ToString() + "</Data></Cell>");
                    sb.AppendLine(
"   </Row>");
                }
            }

            
// 表结束
            sb.AppendLine("  </Table>");
            sb.AppendLine(
" </Worksheet>");
            sb.AppendLine(
"</Workbook>");
            
return sb.ToString();
        }

 

此外需注意,必须导出为 UTF-8格式的xml,否则excel 无法打开该文件,会报错滴~

posted @ 2008-07-31 15:54 Kevin Cheng 阅读(213) | 评论 (0) | 编辑
 

2007年12月10日

隐藏ASP.NET 2.0 Wizard控件的完成按钮

kevin cheng 2007-12-10
这冬冬烦了我一下午,以下是解决思路:
(1)Wizard并没有提供直接访问导航按钮的方式,必须自己用FindControl来找到它
(2)使用FindControl找到的导航按钮并不能直接用Visible=false来隐藏(可能和wizard部件的生成顺序有关)
(3)可使用control.Parent.Remove(control)的方法移除之,如:

// 隐藏完成按钮
void HideFinishButton(Wizard wizard)
{
    Button btn 
= wizard.FindControl("FinishNavigationTemplateContainerID").FindControl("FinishButton") as Button;
    btn.Parent.Controls.Remove(btn);
    
//btn.Visible = false;  // 此句无任何效果!
}
posted @ 2007-12-10 23:00 Kevin Cheng 阅读(276) | 评论 (0) | 编辑
 

2007年6月18日

整理的 AjaxControlToolkit.chm ,希望对大家有用
下载:AjaxControlToolkit.rar
posted @ 2007-06-18 15:33 Kevin Cheng 阅读(1305) | 评论 (7) | 编辑
 

2007年5月29日

发布AccessConsole(Access 控制台工具)

Kevin Cheng 2007-05

这玩意是用来操作access数据库的,尽量模仿oracle的sqlplus,没什么好介绍的了(可用help命令或者-h参数查看帮助),自己用着玩吧。希望对大家有帮助。
Download

posted @ 2007-05-29 13:05 Kevin Cheng 阅读(565) | 评论 (4) | 编辑
 

2007年3月13日

用 System.Xml 读写XML 整理文档

example
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="bb" Url="aa" Desc="aa" />
      <Link Cat="cc" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
    </LinkLibrary>


XML概念
    Root        XML根节点,只能且必须有一个(以上为LinkLibrary)
    Element     节点元素(如Link)
    Attribute   节点属性(如Cat, Url, Desc)
    Content     内容(非空白文本、CDATA、Element、EndElement、EntityReference 或 EndEntity)节点

 

System.Xml空间
    以下类适合快速流式读写XML文件(注:DOM适合随机读写)
    XmlReader, XmlWriter,
    XmlTextReader, XmlTextWriter
    XmlValidatingReader, XmlValidatingWriter    添加了DTD和模式验证,因此提供了数据的有效性验证
    XmlNodeReader, XmlNodeWriter                把XmlNode作为其源


节点类型(public enum XmlNodeType)
     XmlDeclaration        XML 声明(例如,<?xml version='1.0'?>)。
     Attribute             属性(例如,id='123')。
     CDATA                 CDATA 节(例如,<![CDATA[my escaped text]]>)。
     Comment               注释(例如,<!-- my comment -->)
     Document              作为文档树的根的文档对象提供对整个 XML 文档的访问。
     DocumentFragment      文档片段。
     DocumentType          由以下标记指示的文档类型声明(例如,<!DOCTYPE...>)。
     Element               元素(例如,<item>)。
     EndElement            末尾元素标记(例如,</item>)。
     Entity                实体声明(例如,<!ENTITY...>)。
     EndEntity             由于调用 ResolveEntity 而使 XmlReader 到达实体替换的末尾时返回。 
     EntityReference       实体引用(例如,&num;)。
     None                  如果未调用 Read 方法,则由 XmlReader 返回。 
     Notation              文档类型声明中的表示法(例如,<!NOTATION...>)。
     ProcessingInstruction 处理指令(例如,<?pi test?>)。
     SignificantWhitespace 混合内容模型中标记间的空白或 xml:space="preserve" 范围内的空白。 
     Text                  节点的文本内容。
     Whitespace            标记间的空白。 
    


------------------------------------------------------------------------
使用XmlTextReader快速读取
------------------------------------------------------------------------
创建
    打开            XmlTextReader reader = new XmlTextReader("*.xml");
    关闭            reader.Close();

属性
    常用
        HasAttributes            获取一个值,该值指示当前节点是否有任何属性。(从 XmlReader 继承。)
        HasValue                 获取一个值,该值指示当前节点是否可以具有非 String.Empty 的 Value。
        AttributeCount           获取当前节点上的属性数。
        Value                    获取当前节点的文本值。
        ValueType                获取当前节点的公共语言运行库 (CLR) 类型。(从 XmlReader 继承。)
        Name                     获取当前节点的限定名。
    其它
        BaseURI                  获取当前节点的基 URI。
        CanReadBinaryContent     获取一个值,该值指示 XmlTextReader 是否实现二进制内容读取方法。
        CanReadValueChunk        获取一个值,该值指示 XmlTextReader 是否实现 ReadValueChunk 方法。
        CanResolveEntity         获取一个值,该值指示此读取器是否可以分析和解析实体。
        Depth                    获取 XML 文档中当前节点的深度。
        Encoding                 获取文档的编码方式。
        EntityHandling           获取或设置一个值,该值指定读取器如何处理实体。
        EOF                      获取一个值,该值指示读取器是否定位在流的结尾。
        IsDefault                获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的属性。
        IsEmptyElement           获取一个值,该值指示当前节点是否为空元素(例如,<MyElement/>)。
        Item                     当在派生类中被重写时,获取此属性的值。(从 XmlReader 继承。)
        LineNumber               获取当前行号。
        LinePosition             获取当前行位置。
        LocalName                获取当前节点的本地名称。
        Namespaces               获取或设置一个值,该值指示是否进行命名空间支持。
        NamespaceURI             获取读取器定位在的节点的命名空间 URI(采用 W3C 命名空间规范中定义的形式)。
        NameTable                获取与此实现关联的 XmlNameTable。
        NodeType                 获取当前节点的类型。
        Normalization            获取或设置一个值,该值指示是否正常化空白和属性值。
        Prefix                   获取与当前节点关联的命名空间前缀。
        ProhibitDtd              获取或设置一个值,该值指示是否允许 DTD 处理。
        QuoteChar                获取用于括起属性节点值的引号字符。
        ReadState                获取读取器的状态。
        SchemaInfo               获取作为架构验证结果分配给当前节点的架构信息。(从 XmlReader 继承。)
        Settings                 获取用于创建此 XmlTextReader 实例的 XmlReaderSettings 对象。
        WhitespaceHandling       获取或设置一个值,该值指定如何处理空白。
        XmlLang                  获取当前 xml:lang 范围。
        XmlResolver              设置用于解析 DTD 引用的 XmlResolver。
        XmlSpace                 获取当前 xml:space 范围。

方法
    定位           
        MoveToAttribute            移动到指定的属性。 
        MoveToContent              检查当前节点是否是内容节点, 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。
        MoveToElement              移动到包含当前属性节点的元素
        MoveToFirstAttribute       移动到第一个属性
        MoveToNextAttribute      移动到下一个属性
        Skip                                跳过当前节点的子级。 
        IsStartElement                测试当前内容节点是否是开始标记。
 
    基本读取           
        Read                       读取一个节点
        ReadString                 将元素或文本节点的内容读取为一个字符串。


    读取特定类型
        ReadBase64                 对 Base64 进行解码并返回解码的二进制字节。
        ReadBinHex                 对 BinHex 进行解码并返回解码后的二进制字节
        ReadChars                  将元素的文本内容读入字符缓冲区。通过连续调用此方法,可以读取大的嵌入文本流。
        ReadValueChunk             读取嵌入在 XML 文档中的大量文本流。 (从 XmlReader 继承。)
        ReadInnerXml               将内部XML节点内容读到一个字符串中
        ReadOuterXml               所有XML节点内容(包括自身节点)

    读取节点
        ReadStartElement           检查当前节点是否为元素并将读取器推进到下一个节点。
        ReadElementString          这是一个用于读取简单纯文本元素的 Helper 方法。
        ReadAttributeValue         将属性值分析为一个或多个 Text、EntityReference 或 EndEntity 节点
        ReadEndElement             检查当前内容节点是否为结束标记并将读取器推进到下一个节点。
        GetAttribute                   获取属性的值。 

    读取内容并转化
        ReadContentAs...           将内容作为指定类型的对象读取。 (从 XmlReader 继承。)
        ReadElementContentAs...    读取当前元素,并将内容作为指定类型的对象返回。 (从 XmlReader 继承。)

    追溯读取
        ReadToFollowing            一直读取,直到找到具有指定限定名的元素
        ReadToDescendant           让 XmlReader 前进到下一个匹配的子代元素。
        ReadToNextSibling          让 XmlReader 前进到下一个匹配的同级元素。
        GetRemainder               获取已缓冲的 XML 剩余部分。
        ReadSubtree                返回新的 XmlReader 实例,此实例可用于读取当前节点及其所有子节点。
 

 

 

------------------------------------------------------------------------
使用XmlTextWriter快速写入
------------------------------------------------------------------------
开闭           
    XmlTextWriter writer = new XmlTextWriter(@"c:\mywriter.xml", null);
    writer.Close();
   
起止XML文档 (<?xml version="1.0"?>
    writer.WriteStartDocument();
    writer.EndDocument();

声明XML格式
    writer.Formatting  = Formatting.Indented;
    writer.Indentation = 缩进字符数
    writer.IndentChar  = 缩进字符
    writer.QuoteChar   = 单引号|双引号

输出注释 (<!-- comment text -->)
    writer.WriteComment("comment text");

输出元素 (<Element>ElementVal</Element>)
    writer.WriteElementString("Element", "ElementVal");
    或者
    writer.StartElement("Element");
    writer.WriteString("ElementVal");
    writer.EndElement();

输出元素属性 (<Element Property="PropertyVal">ElementVal</Element>)
    writer.StartElement("Element");
    writer.WriteAttributeString("Property", "PropertyVal");
    writer.WriteString("ElementVal");
    writer.EndElement();

输出CDATA (<!CDATA>....</CDATA>
    WriteCData("....")

输出字符缓冲区文本
    WriteChars(char[], startPos, length)
   
   

------------------------------------------------------------------------
读例程
------------------------------------------------------------------------
XML文件
    <!-- sample xml file -->
    <bookstore>
      <book genre='novel' ISBN='10-861003-324'>
        <title>The Handmaid's Tale</title>
        <price>19.95</price>
      </book>
      <book genre='novel' ISBN='1-861001-57-5'>
        <title>Pride And Prejudice</title>
        <price>24.95</price>
      </book>
    </bookstore>


取每个书节点上的ISBN属性
    using (XmlReader reader = XmlReader.Create("books.xml"))
    {
        reader.ReadToFollowing("book");
        do {
           Console.WriteLine("ISBN: {0}", reader.GetAttribute("ISBN"));
        } while (reader.ReadToNextSibling("book"));
    }

跳到子节点
    using (XmlReader reader = XmlReader.Create("2books.xml"))
    {
        reader.MoveToContent();                 // bookstore
        reader.ReadToDescendant("book");        // 第一个book
        reader.Skip(); //Skip the first book.   // 第二个book
        ...
    }
   
挖到子节点
    using (XmlReader reader = XmlReader.Create("book3.xml"))
    {
        reader.Read();
        reader.ReadStartElement("book");
            reader.ReadStartElement("title");
                Console.WriteLine("The content of the title element:  {0}", reader.ReadString());
            reader.ReadEndElement();
            reader.ReadStartElement("price");
                Console.WriteLine("The content of the price element:  {0}", reader.ReadString());
            reader.ReadEndElement();
        reader.ReadEndElement();
    }

 

读到指定位置  
   FileStream fs = new FileStream("..\\..\\..\\books.xml", FileMode.Open);
   XmlTextReader tr = new XmlTextReader(fs);
   while(!tr.EOF)
   {
      // 查找类型为XmlNodeType.Element和名称为title的节点
      if(tr.MoveToContent() == XmlNodeType.Element && tr.Name=="title")
      {
         listBox1.Items.Add(tr.ReadElementString());
      }
      else
      {
         tr.Read();
      }
    }

遍历元素属性
   string fileName = "..\\..\\..\\books.xml";
   XmlTextReader tr = new XmlTextReader(fileName);
   while(tr.Read())
   {
      //check to see if it's a NodeType element
      if(tr.NodeType == XmlNodeType.Element) 
      {
         //if it's an element, then let's look at the attributes.
         for(int i = 0; i < tr.AttributeCount; i++) {
            listBox1.Items.Add(tr.GetAttribute(i));
      }
}

   
------------------------------------------------------------------------
写例程
------------------------------------------------------------------------
     XmlTextWriter writer = new XmlTextWriter (filename, null);

     //Use indenting for readability.
     writer.Formatting = Formatting.Indented;

     //xml声明(Write the XML delcaration. )
     writer.WriteStartDocument();

     //预处理指示(Write the ProcessingInstruction node.)
     String PItext="type='text/xsl' href='book.xsl'";
     writer.WriteProcessingInstruction("xml-stylesheet", PItext);

     //文档类型(Write the DocumentType node.)
     writer.WriteDocType("book", null , null, "<!ENTITY h 'hardcover'>");
       
     //注释(Write a Comment node.)
     writer.WriteComment("sample XML");
   
     //根元素(Write a root element.)
     writer.WriteStartElement("book");

     //属性值(Write the genre attribute.)
     writer.WriteAttributeString("genre", "novel");
   
     //属性值(Write the ISBN attribute.)
     writer.WriteAttributeString("ISBN", "1-8630-014");

     //Write the title.
     writer.WriteElementString("title", "The Handmaid's Tale");
             
     //Write the style element.
     writer.WriteStartElement("style");
     writer.WriteEntityRef("h");
     writer.WriteEndElement();

     //文本元素节点(Write the price.)
     writer.WriteElementString("price", "19.95");

     //[CDATA]
     writer.WriteCData("Prices 15% off!!");

     //Write the close tag for the root element.
     writer.WriteEndElement();
            
     writer.WriteEndDocument();

     //Write the XML to file and close the writer.
     writer.Flush();
     writer.Close(); 

     //Load the file into an XmlDocument to ensure well formed XML.
     XmlDocument doc = new XmlDocument();
     //Preserve white space for readability.
     doc.PreserveWhitespace = true;
     //Load the file.
     doc.Load(filename); 
   
     //Display the XML content to the console.
     Console.Write(doc.InnerXml); 


------------------------------------------------------------------------
带验证的读写
------------------------------------------------------------------------
    books.xml
        <?xml version='1.0'?>
        <!-- This file represents a fragment of a book store inventory database -->
        <bookstore xmlns="x-schema:books.xdr">
           <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
              <title>The Autobiography of Benjamin Franklin</title>
              <author>
                 <first-name>Benjamin</first-name>
                 <list-name>Franklin</last-name>
              </author>
              <price>8.99</price>
           </book>
           ...
        </bookstore>
    books.xdr
        <?xml version="1.0"?>
        <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
           <ElementType FTEL="first-name" content="textOnly"/>
           <ElementType FTEL="last-name" content="textOnly"/>
           <ElementType FTEL="name" content="textOnly"/>
           <ElementType FTEL="price" content="textOnly" dt:type="fixed.14.4"/>
           <ElementType FTEL="author" content="eltOnly" order="one">
              <group order="seq">
                 <element type="name"/>
              </group>
              <group order="seq">
                 <element type="first-name"/>
                 <element type="last-name"/>
              </group>
           </ElementType>
           <ElementType FTEL="title" content="textOnly"/>
           <AttributeType FTEL="genre" dt:type="string"/>
           <ElementType FTEL="book" content="eltOnly">
              <attribute type="genre" required="yes"/>
              <element type="title"/>
              <element type="author"/>
              <element type="price"/>
           </ElementType>
           <ElementType FTEL="bookstore" content="eltOnly">
              <element type="book"/>
           </ElementType>
        </Schema>
    cs
        using System.Xml.Schema;
        protected void button1_Click (object sender, System.EventArgs e)
        {
           //change this to match your path structure.
           string fileName = "..\\..\\..\\booksVal.xml";
           XmlTextReader tr = new XmlTextReader(fileName);
           XmlValidatingReader trv = new XmlValidatingReader(tr);
        
           //Set validation type
           trv.ValidationType=ValidationType.XDR;
           //Add in the Validation eventhandler
           trv.ValidationEventHandler += new ValidationEventHandler(this.ValidationEvent);
        
           //Read in node at a time       
           while(trv.Read()) 
           {
              if(trv.NodeType == XmlNodeType.Text)
              listBox1.Items.Add(trv.Value);
           }
        }
        public void ValidationEvent (object sender, ValidationEventArgs args)
        {
           MessageBox.Show(args.Message);
        }

posted @ 2007-03-13 22:01 Kevin Cheng 阅读(2783) | 评论 (6) | 编辑
 
XML序列化与反序列化 整理文档

XML序列化与反序列化
    // OBJECT -> XML
    public static void SaveXml(string filePath, object obj) { SaveXml(filePath, obj, obj.GetType()); }
    public static void SaveXml(string filePath, object obj, System.Type type)
    {
        using (System.IO.StreamWriter writer = new System.IO.StreamWriter(filePath))
        {
            System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(type);
            xs.Serialize(writer, obj);
            writer.Close();
        }
    }
    // XML -> OBJECT
    public static object LoadXml(string filePath, System.Type type)
    {
        if (!System.IO.File.Exists(filePath))
            return null;
        using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
        {
            System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(type);
            object obj = xs.Deserialize(reader);
            reader.Close();
            return obj;
        }
    }

相关的常用Attribute(命名空间System.Xml.Serialization )
    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", IsNullable=false)]  // 指定根
    [XmlIgnoreAttribute]                                                                      // 跳过不序列化
    [XmlArrayAttribute("Items")] public OrderedItem[] OrderedItems;                           // 层次序列化: <Items><OrderedItem.../><OrderedItem.../>..</Items>
    [XmlElementAttribute(ElementName="Link", IsNullable=false)] public Link[] Links;          // 平面序列化: <Link ..../><Link .../>...
    [XmlAttribute("Cat")] public string Cat;                                                  // 表现为属性<... Cat=.. />
    [XmlElementAttribute(IsNullable=false)]                                                   // 表现为节点<Cat>..</cat>


相关的全部Attribute(命名空间System.Xml.Serialization )
    XmlAttributes                     表示一个特性对象的集合,这些对象控制 XmlSerializer 如何序列化和反序列化对象。
    XmlArrayAttribute                 指定 XmlSerializer 应将特定的类成员序列化为 XML 元素数组。
    XmlArrayItemAttribute             指定 XmlSerializer 可以放置在序列化数组中的派生类型。
    XmlArrayItemAttributes            表示 XmlArrayItemAttribute 对象的集合。
    XmlAttributeAttribute             指定 XmlSerializer 应将类成员作为 XML 特性序列化。
    XmlChoiceIdentifierAttribute      指定可以通过使用枚举来进一步消除成员的歧义。
    XmlElementAttribute               在 XmlSerializer 序列化或反序列化包含对象时,指示公共字段或属性表示 XML 元素。
    XmlElementAttributes              表示 XmlElementAttribute 的集合,XmlSerializer 将其用于它重写序列化类的默认方式。
    XmlEnumAttribute                  控制 XmlSerializer 如何序列化枚举成员。
    XmlIgnoreAttribute                指示 XmlSerializer 的 Serialize 方法不序列化公共字段或公共读/写属性值。
    XmlIncludeAttribute               允许 XmlSerializer 在它序列化或反序列化对象时识别类型。
    XmlRootAttribute                  控制视为 XML 根元素的属性目标的 XML 序列化。
    XmlTextAttribute                  当序列化或反序列化包含类时,向 XmlSerializer 指示应将此成员作为 XML 文本处理。
    XmlTypeAttribute                  控制当属性目标由 XmlSerializer 序列化时生成的 XML 架构。
    XmlAnyAttributeAttribute          指定成员(返回 XmlAttribute 对象的数组的字段)可以包含任何 XML 属性。
    XmlAnyElementAttribute            指定成员(返回 XmlElement 或 XmlNode 对象的数组的字段)可以包含对象,该对象表示在序列化或反序列化的对象中没有相应成员的所有 XML 元素。
    XmlAnyElementAttributes           表示 XmlAnyElementAttribute 对象的集合。
    XmlAttributeEventArgs             为 UnknownAttribute 事件提供数据。
    XmlAttributeOverrides             允许您在使用 XmlSerializer 序列化或反序列化对象时重写属性、字段和类特性。
    XmlElementEventArgs               为 UnknownElement 事件提供数据。
    XmlNamespaceDeclarationsAttribute 指定目标属性、参数、返回值或类成员包含与 XML 文档中所用命名空间关联的前缀。
    XmlNodeEventArgs                  为 UnknownNode 事件提供数据。
    XmlSerializer                     将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。
    XmlSerializerNamespaces           包含 XmlSerializer 用于在 XML 文档实例中生成限定名的 XML 命名空间和前缀。
    XmlTypeMapping                    包含从一种类型到另一种类型的映射。


xml序列化答疑
    (1)需序列化的字段必须是公共的(public)
    (2)需要序列化的类都必须有一个无参的构造函数
    (3)枚举变量可序列化为字符串,无需用[XmlInclude]
    (4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该规则递归作用到子元素
        如导出ArrayList对象,若其成员是自定义的,需预包含处理:
        using System.Xml.Serialization;
        [XmlInclude(typeof(自定义类))]
    (5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
        也就是说:针对值类型(如结构体)该功能是实效的
        若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
        若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
    (6)真正无法XML序列化的情况
        某些类就是无法XML序列化的(即使使用了[XmlInclude])
            IDictionary(如HashTable)
            System.Drawing.Color
            System.Drawing.Font
            SecurityAttribute声明
        父类对象赋予子类对象值的情况
        对象间循环引用
    (7)对于无法XML序列化的对象,可考虑
        使用自定义xml序列化(实现IXmlSerializable接口)
        实现IDictionary的类,可考虑(1)用其它集合类替代;(2)用类封装之,并提供Add和this函数
        某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数
        过于复杂的对象用xml序列化不便的话,可考虑用二进制序列化


------------------------------------------------------------------------------------
高级议题
------------------------------------------------------------------------------------
序列化中异常的扑捉
    使用Exception.Message只会得到简单的信息“行***错误"
    可以使用Exception.InnerException.Message得到更详尽的信息

可使用事件代理来处理解析不了的XML节点
    XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
    serializer.UnknownNode+= new XmlNodeEventHandler(serializer_UnknownNode);
    serializer.UnknownAttribute+= new  XmlAttributeEventHandler(serializer_UnknownAttribute);
    protected void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
    {
      Console.WriteLine("Unknown Node:" +   e.Name + "\t" + e.Text);
    }
    protected void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
    {
      System.Xml.XmlAttribute attr = e.Attr;
      Console.WriteLine("Unknown attribute " +  attr.Name + "='" + attr.Value + "'");
    }

集合类(IEnumerable, ICollection)必须满足下列规则才可XML序列化:
    - 不得实现 IDictionary。
    - 必须有一个 Add 方法,该方法不是由该接口定义的,因为它通常是为该集合将要容纳的专用类型而创建的
    - 必须有一个索引器, 且参数为 System.Int32 (C# int)
    - 在 Add、Count 和索引器中不能有任何安全特性(SecurityAttribute)
    可序列化集合类例程:
        public class PublisherCollection : CollectionBase
        {
          public int Add(Publisher value)
          {
            return base.InnerList.Add(value);
          }
          public Publisher this[int idx]
          {
            get { return (Publisher) base.InnerList[idx]; }
            set { base.InnerList[idx] = value; }
          }
        }


某些类是以程序集的形式提供的,无法修改其源码。可用XmlAttributeOverrides设置其序列化特性
     XML目标
        <?xml version="1.0" encoding="utf-8"?>
        <Inventory xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
           <Product>
              <ProductID>100</ProductID>
              <ProductName>Product Thing</ProductName>
              <SupplierID>10</SupplierID>
           </Product>
           <Book>
              <ProductID>101</ProductID>
              <ProductName>How to Use Your New Product Thing</ProductName>
              <SupplierID>10</SupplierID>
              <ISBN>123456789</ISBN>
           </Book>
        </Inventory>
    源类(无法修改)
        public class Inventory
        {
           private Product[] stuff;
           public Inventory() {}
           public Product[] InventoryItems {get {return stuff;} set {stuff=value;}}
        }
    附加XmlAttributeOverrides后即可序列化
       XmlAttributes attrs = new XmlAttributes();
       attrs.XmlElements.Add(new XmlElementAttribute("Book", typeof(BookProduct)));
       attrs.XmlElements.Add(new XmlElementAttribute("Product", typeof(Product)));
       //add to the Attributes collection
       XmlAttributeOverrides attrOver = new XmlAttributeOverrides();
       attrOver.Add(typeof(Inventory), "InventoryItems", attrs);
       //deserialize and load data into the listbox from deserialized object
       FileStream f=new FileStream("..\\..\\..\\inventory.xml",FileMode.Open);
       XmlSerializer newSr=new XmlSerializer(typeof(Inventory), attrOver);
       Inventory newInv = (Inventory)newSr.Deserialize(f);

 

 

------------------------------------------------------------------------------------
最简单的示例
-------------------------------------------------------------------------------------
类设计
    public class MyClass  {public MyObject MyObjectProperty;}
    public class MyObject {public string ObjectName;}

序列化的 XML:
    <MyClass>
        <MyObjectProperty>
            <Objectname>My String</ObjectName>
        </MyObjectProperty>
    </MyClass>


 
------------------------------------------------------------------------------------
示例: 序列化数组,并限制数组元素类型
-------------------------------------------------------------------------------------
类设计
    public class Things
    {
       [XmlElement(DataType = typeof(string)), XmlElement(DataType = typeof(int))]
       public object[] StringsAndInts;
    }

生成的 XML 可能为:
    <Things>
       <string>Hello</string>
       <int>999</int>
       <string>World</string>
    </Things>

 

-------------------------------------------------------------------------------------
示例: 序列化数组
-------------------------------------------------------------------------------------
类设计
    using System.Xml.Serialization;
    [XmlRootAttribute("LinkLibrary", IsNullable = false, Namespace="http://www.wztelecom.cn")]
    public class LinkLib
    {
        [XmlElementAttribute(ElementName="Link", IsNullable=false)]
        public Link[] Links;
        public LinkLib()
        {
            Links = new Link[50];
            Links[0] = new Link("aa", "aa", "aa");
            Links[1] = new Link("bb", "aa", "aa");
            Links[2] = new Link("cc", "aa", "aa");
            Links[3] = new Link("aa", "aa", "aa");
            Links[4] = new Link("aa", "aa", "aa");
            Links[5] = new Link("aa", "aa", "aa");
            Links[6] = new Link("aa", "aa", "aa");
            Links[7] = new Link("aa", "aa", "aa");
            Links[8] = new Link("aa", "aa", "aa");
            Links[9] = new Link("aa", "aa", "aa");
        }
    }
    public class Link
    {
        [XmlAttribute("Cat")] public string Cat;
        [XmlAttribute("Url")] public string Url;
        [XmlAttribute("Desc")]public string Desc;
        public Link(){}
        public Link(string cat, string url, string desc)
        {
            Cat = cat;
            Url = url;
            Desc = desc;
        }
    }

目标XML文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="bb" Url="aa" Desc="aa" />
      <Link Cat="cc" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
    </LinkLibrary>

若使用[XmlArrayAttribute("Links")] public Link[] Links;则序列化后的xml文件会多出一层:
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <Links>
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="bb" Url="aa" Desc="aa" />
              <Link Cat="cc" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
         </Links>
    </LinkLibrary>

 

-------------------------------------------------------------------------------------
示例:使用自定义序列化序列化Dictionary对象
-------------------------------------------------------------------------------------
XML目标
    <?xml version="1.0" encoding="utf-8"?>
    <FactTableDef>
      <Name>FactTableDef1</Name>
      <Owner>owner1</Owner>
      <SourceTable>sourceTable1</SourceTable>
      <ColumnMeasureMaps>
        <Map Column="column1" Measure="Measure1" />
        <Map Column="column2" Measure="Measure2" />
        <Map Column="column3" Measure="Measure3" />
      </ColumnMeasureMaps>
      <ColumnDimensionMaps>
        <Map Column="column4" Dimension="Dimension4" />
        <Map Column="column5" Dimension="Dimension5" />
        <Map Column="column6" Dimension="Dimension6" />
      </ColumnDimensionMaps>
    </FactTableDef>

类源码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Xml;
    using System.Xml.Serialization;

    namespace WZDM.OLAP
    {
        [System.Serializable()]
        [XmlInclude(typeof(FactTableDef))]
        public class FactTableDef : System.Xml.Serialization.IXmlSerializable
        {
            public string Name;               // 名称
            public string Owner;              // 事实表属主
            public string SourceTable;        // 源表
            public Dictionary<string, string> ColumnMeasureMaps;   // 字段和量度对应关系
            public Dictionary<string, string> ColumnDimensionMaps; // 字段和维度对应关系
   
   
            public FactTableDef() { }
            ...
   
            public void WriteXml(System.Xml.XmlWriter writer)
            {
          &n