在我的上一篇文章《 C# 中使用 XML ——读取 XML 》中和大家讨论了如何使用 .NET Framework 中提供的类在 C# 中读取 XML 以及读取的一些相关概念,那么今天就说一说如何在 C# 中编写 XML 文档,起初我觉得用编程的方式去编写 XML 简直就是自讨苦吃,后来想想还是觉得挺有用的,我想 Microsoft 那班家伙能编出这些类来应该不是仅仅为了向比尔 i 盖茨交差吧!至于它的用处嘛 …… 比如说做安装程序啊!我们可以根据在安装过程中用户所选的选项以及一些设置来生成相应的 XML 文档再根据 XML 文档来初始化我们的应用程序。空洞的话不说那么多了,下面我们来了解一下具体的实现细节。
要编写 XML 同样是采用流的概念,在 .NET 中编写 XML 的细节是作为 XmlWriter 类来实现的,但该类是抽象类不能够实例化,为此,我们要想在程序中访问它的方法以实现编写 XML 的愿望,必需使用它的派生类 XmlTextWriter ,该类提供了一系列的属性和方法为我们编写 XML 做准备,下面将详细的介绍这个类:
** 构造函数: ** ** **
public XmlTextWriter(TextWriter);
public XmlTextWriter(Stream, Encoding);
public XmlTextWriter(string, Encoding);
第一个构造函数是把现有的 TextWriter 实例传递过去, System.IO.TextWriter 类是一个有序的字符流
第二个构造函数是把要写入的流作为第一个参数,第二个参数是指定 XML 文档的编码方式,默认是 UTF8 ,可取 Encoding 的枚举值,流可以是 FileStream , MemoryStream , NetworkStream 等等
第三个构造函数是把希望写入的文件名当作一个字符串(如果存在,就重写该文件)传递给第一个参数,第二个参数指定编码方式
** 常用的方法: **
WriterStartDocument() 和 WriterEndDocument() 方法:
第一个方法用来编写 XML 声明部分,如:
第二个方法用来 关闭任何打开的元素或属性并将编写器重新设置为 Start 状态。
WriterStartElement() 和 WriteEndElement() 方法:
第一个方法用来写出指定的开始标记,该方法有以下几个重载:
WriterStartElement(string localname)
使用传递的字符串作为元素的本地名称
WriterStartElement(string localname,string namespace)
第一个参数指定元素的本地名称,第二个参数指定元素所在的命名空间
WriterStartElement(string prefix,string localname,string namespace)
第一个参数指定元素的前缀,第二个参数指定元素的本地名称,第三个参数指定元素所在的命名空间
第二个方法用来写出与开始元素对应的关闭元素,如果开始元素不包含任何内容,将用一个 ”/>” 做为关闭元素
WriterStartAttribute() 和 WriterEndAttribute() 方法:
第一个方法用于编写一个属性的开头,该方法有两个重载:
WriterStartAttribute(string localname,string namespace)
第一个参数指定属性的本地名称,第二个参数指定属性所在的命名空间
WriterStartAttribute(string prefix,string localname,string namespace)
第一个参数指定属性的前缀,第二个参数指定属性的本地名称,第三个参数指定属性所在的命名空间
第二个方法用于关闭 WriterStartAttribute 创建的属性
WriterElementString() 方法:
该方法可以创建一个包含字符串值的元素,它有以下重载:
WriterElementString(string localname,string value)
如果编写这样的代码: WriterElementString(“para”,”Some text”) 将输出:
1<para>Some text</para>
WriterElementString(string localname,string namespace,string value)
如果编写这样的代码: WriterElementString(“para”,” http://www.w3.org/ns ”,”Some text”) 将输出:
1<para http:="" ns="" www.w3.org="" xmlns="”" ”="">Some text</para>
如果编写嵌套几级的元素可使用 WriterStartElement() 和 WriterEndElement() 方法,如果编写直接包含内容的元素可以使用该方法
WriterAttributeString() 方法:
类似与 WriterElementString() 方法,在使用上如果属性的值当中不包含实体可直接使用该方法来写出属性,如果属性值包含实体可使用 WriterStartAttribute() 和 WriterEndAttribute() 方法,例如要写出这样的 XML ——
1<para author="”Do&0241;a&L.Perez”/">, 可编写以下代码:
2
3WriterStartElement(“para”);
4
5WriterStartAttribute(“author”,null);
6
7WriterString(“Do”);
8
9WriterCharEntiry(“~n”);
10
11WriterString(“a”);
12
13WriterCharEntiry(“&”);
14
15WriterString(“L.Perez”);
16
17WriterEndAttribute();
18
19WriterEndElement();
20
21该方法有以下重载:
22
23WriterAttributeString(string localname,string value);
24
25WriterAttributeString(string localname,string namespace,string value);
26
27WriterAttributeString(string prefx, string localname,string namespace,string value);
28
29WriterNode(XmlReader reader,bool defattr) 方法:
30
31该方法可以从 XmlReader 读取器中复制节点并把它们写入 XmlWriter 流中,第一个参数是 XmlReader 的实例,第二个参数接受一个布尔值,决定是否复制元素中的属性,考虑下面 XML 片段:
32
33<para>
34<sent>
35
36The<b>XmlWriter</b>class writes XML content to a Stream.
37
38</sent>
39</para>
40
41以下代码复制其中的片段, reader 代表 XmlReader 的实例 writer 代表 XmlWriter 类的实例:
42
43while(reader.Read())
44
45{
46
47if (reader.Name == ”sent” && reader.NodeType == XmlNodeType.Element)
48
49{
50
51writer.WriterNode(reader,true);
52
53}
54
55}
56
57得到以下输出:
58
59<sent>
60
61The<b>XmlWriter</b>class writes XML content to a Stream.
62
63</sent>
64
65WriterComment(string text) 方法:用于写出注释
66
67WriterString(string text) 方法:用于写出文本
68
69WriterCData(string text) 方法:写出 CDATA 数据块
70
71WriterBase64(byte[] buffer,int index,int count) 方法:将指定的二进制字节编码为 Base64 并写出结果文本
72
73Flush() :将缓冲区中的所有内容刷新到基础流,并同时刷新基础流
74
75Close() :关闭此流和基础流
76
77以上对 XmlTextWriter 类的一些重要方法做了简单介绍,下面我们就来看一个例程,看看在程序中如何使用这些方法,照样还是先来看下运行效果图:
78
79
80
81Example1 按纽将向一个文件写出 XML 声明和一个元素节点以及节点内的文本, Example2 按纽将在 Example1 的基础上添加属性节点,嵌套元素以及文本, WriteNode 按纽使用 WriterNode() 方法在现有读取器中复制该读取器中的所有元素及属性并写到一个新的 XML 文档中, Example3 按纽将写一份完整的 XML 文档, Example4 按纽在 Example3 按纽的基础上另外生成一份文档并向该文档中追加 CDATA 部分, Example5 按纽将使用 WriterBase64() 方法对一幅图片进行编码并将编码后的数据写到 XML 文档中, Example6 按纽将使用 Example5 按纽中生成的 XML 读取其中数据并对其中编码数据进行解码最后生成一张图片。
82
83以下是功能实现代码:
84
85
86namespace XMLWriting
87
88{
89
90using System;
91
92using System.IO;
93
94using System.Text;
95
96using System.Xml;
97
98using System.Drawing;
99
100using System.Collections;
101
102using System.ComponentModel;
103
104using System.Windows.Forms;
105
106using System.Data;
107
108/// <summary>
109
110/// Form1 的摘要说明。
111
112/// </summary>
113
114public class Form1 : System.Windows.Forms.Form
115
116{
117
118private System.Windows.Forms.TextBox textBox1;
119
120private System.Windows.Forms.Button button1;
121
122private System.Windows.Forms.Button button2;
123
124private System.Windows.Forms.Button button3;
125
126private System.Windows.Forms.Button button4;
127
128private System.Windows.Forms.Button button5;
129
130private System.Windows.Forms.Button button6;
131
132private System.Windows.Forms.Button button7;
133
134/// <summary>
135
136/// 必需的设计器变量。
137
138/// </summary>
139
140private System.ComponentModel.Container components = null ;
141
142public Form1()
143
144{
145
146//
147
148// Windows 窗体设计器支持所必需的
149
150//
151
152InitializeComponent();
153
154//
155
156// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
157
158//
159
160}
161
162/// <summary>
163
164/// 清理所有正在使用的资源。
165
166/// </summary>
167
168protected override void Dispose( bool disposing )
169
170{
171
172if ( disposing )
173
174{
175
176if (components != null )
177
178{
179
180components.Dispose();
181
182}
183
184}
185
186<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; m</para>