在我的上一篇文章《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声明部分,如:<?xml version=”1.0” encoding=”UTF-8” ?>
第二个方法用来关闭任何打开的元素或属性并将编写器重新设置为 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”) 将输出:<para>Some text</para>
WriterElementString(string localname,string namespace,string value)
如果编写这样的代码:WriterElementString(“para”,”http://www.w3.org/ns”,” Some text”) 将输出:<para xmlns=”http://www.w3.org/ns”>Some text</para>
如果编写嵌套几级的元素可使用WriterStartElement()和WriterEndElement()方法,如果编写直接包含内容的元素可以使用该方法
WriterAttributeString()方法:
类似与WriterElementString()方法,在使用上如果属性的值当中不包含实体可直接使用该方法来写出属性,如果属性值包 含实体可使用WriterStartAttribute()和WriterEndAttribute()方法,例如要写出这样的XML——<para author=”Do&0241;a&L.Perez”/>,可编写以下代码:
WriterStartElement(“para”);
WriterStartAttribute(“author”,null);
WriterString(“Do”);
WriterCharEntiry(“~n”);
WriterString(“a”);
WriterCharEntiry(“&”);
WriterString(“L.Perez”);
WriterEndAttribute();
WriterEndElement();
该方法有以下重载:
WriterAttributeString(string localname,string value);
WriterAttributeString(string localname,string namespace,string value);
WriterAttributeString(string prefx, string localname,string namespace,string value);
WriterNode(XmlReader reader,bool defattr)方法:
该方法可以从XmlReader读取器中复制节点并把它们写入XmlWriter流中,第一个参数是XmlReader的实例,第二个参数接受一个布尔值,决定是否复制元素中的属性,考虑下面XML片段:
<para>
<sent>
The<b>XmlWriter</b>class writes XML content to a Stream.
</sent>
</para>
以下代码复制其中的片段,reader代表XmlReader的实例writer代表XmlWriter类的实例:
while(reader.Read())
{
if (reader.Name == ”sent” && reader.NodeType == XmlNodeType.Element)
{
writer.WriterNode(reader,true);
}
}
得到以下输出:
<sent>
The<b>XmlWriter</b>class writes XML content to a Stream.
</sent>
WriterComment(string text)方法:用于写出注释
WriterString(string text)方法:用于写出文本
WriterCData(string text)方法:写出CDATA数据块
WriterBase64(byte[] buffer,int index,int count)方法:将指定的二进制字节编码为 Base64 并写出结果文本
Flush():将缓冲区中的所有内容刷新到基础流,并同时刷新基础流 Close():关闭此流和基础流
以上对XmlTextWriter类的一些重要方法做了简单介绍,下面我们就来看一个例程,看看在程序中如何使用这些方法,照样还是先来看下运行效果图:
Example1按纽将向一个文件写出XML声明和一个元素节点以及节点内的文本,Example2按纽将在Example1的基础上添加属 性节点,嵌套元素以及文本,WriteNode按纽使用WriterNode()方法在现有读取器中复制该读取器中的所有元素及属性并写到一个新的XML 文档中,Example3按纽将写一份完整的XML文档,Example4按纽在Example3按纽的基础上另外生成一份文档并向该文档中追加 CDATA部分,Example5按纽将使用WriterBase64()方法对一幅图片进行编码并将编码后的数据写到XML文档中,Example6按 纽将使用Example5按纽中生成的XML读取其中数据并对其中编码数据进行解码最后生成一张图片。
以下是功能实现代码:>>>点击查看
以下是在WriteNode按纽中要使用到的XML文件:
唐诗.xml
<?xml version="1.0" encoding="gb2312"?>
<唐诗>
<五言绝句>
<作者 字号="太白">李白</作者>
<标题>静夜思</标题>
<内容>床前明月光,疑是地上霜。举头望明月,低头思故乡。</内容>
</五言绝句>
<五言绝句>
<作者 字号="太白">李太白</作者>
<标题>春晓</标题>
<内容>春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。</内容>
</五言绝句>
<五言绝句>
<作者 字号="季凌">王之涣</作者>
<标题>登鹤雀楼</标题>
<内容>白日依山尽,黄河入海流。欲穷千里目,更上一层楼</内容>
</五言绝句>
<五言绝句>
<作者>李清照</作者>
<标题>如梦令</标题>
<内容>昨夜风疏雨骤,浓睡不消残酒,试问卷帘人,却道海棠依旧,知否,知否,应是绿肥红瘦。</内容>
</五言绝句>
</唐诗>
要编写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声明部分,如:<?xml version=”1.0” encoding=”UTF-8” ?>
第二个方法用来关闭任何打开的元素或属性并将编写器重新设置为 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”) 将输出:<para>Some text</para>
WriterElementString(string localname,string namespace,string value)
如果编写这样的代码:WriterElementString(“para”,”http://www.w3.org/ns”,” Some text”) 将输出:<para xmlns=”http://www.w3.org/ns”>Some text</para>
如果编写嵌套几级的元素可使用WriterStartElement()和WriterEndElement()方法,如果编写直接包含内容的元素可以使用该方法
WriterAttributeString()方法:
类似与WriterElementString()方法,在使用上如果属性的值当中不包含实体可直接使用该方法来写出属性,如果属性值包 含实体可使用WriterStartAttribute()和WriterEndAttribute()方法,例如要写出这样的XML——<para author=”Do&0241;a&L.Perez”/>,可编写以下代码:
WriterStartElement(“para”);
WriterStartAttribute(“author”,null);
WriterString(“Do”);
WriterCharEntiry(“~n”);
WriterString(“a”);
WriterCharEntiry(“&”);
WriterString(“L.Perez”);
WriterEndAttribute();
WriterEndElement();
该方法有以下重载:
WriterAttributeString(string localname,string value);
WriterAttributeString(string localname,string namespace,string value);
WriterAttributeString(string prefx, string localname,string namespace,string value);
WriterNode(XmlReader reader,bool defattr)方法:
该方法可以从XmlReader读取器中复制节点并把它们写入XmlWriter流中,第一个参数是XmlReader的实例,第二个参数接受一个布尔值,决定是否复制元素中的属性,考虑下面XML片段:
<para>
<sent>
The<b>XmlWriter</b>class writes XML content to a Stream.
</sent>
</para>
以下代码复制其中的片段,reader代表XmlReader的实例writer代表XmlWriter类的实例:
while(reader.Read())
{
if (reader.Name == ”sent” && reader.NodeType == XmlNodeType.Element)
{
writer.WriterNode(reader,true);
}
}
得到以下输出:
<sent>
The<b>XmlWriter</b>class writes XML content to a Stream.
</sent>
WriterComment(string text)方法:用于写出注释
WriterString(string text)方法:用于写出文本
WriterCData(string text)方法:写出CDATA数据块
WriterBase64(byte[] buffer,int index,int count)方法:将指定的二进制字节编码为 Base64 并写出结果文本
Flush():将缓冲区中的所有内容刷新到基础流,并同时刷新基础流 Close():关闭此流和基础流
以上对XmlTextWriter类的一些重要方法做了简单介绍,下面我们就来看一个例程,看看在程序中如何使用这些方法,照样还是先来看下运行效果图:
Example1按纽将向一个文件写出XML声明和一个元素节点以及节点内的文本,Example2按纽将在Example1的基础上添加属 性节点,嵌套元素以及文本,WriteNode按纽使用WriterNode()方法在现有读取器中复制该读取器中的所有元素及属性并写到一个新的XML 文档中,Example3按纽将写一份完整的XML文档,Example4按纽在Example3按纽的基础上另外生成一份文档并向该文档中追加 CDATA部分,Example5按纽将使用WriterBase64()方法对一幅图片进行编码并将编码后的数据写到XML文档中,Example6按 纽将使用Example5按纽中生成的XML读取其中数据并对其中编码数据进行解码最后生成一张图片。
以下是功能实现代码:>>>点击查看
以下是在WriteNode按纽中要使用到的XML文件:
唐诗.xml
<?xml version="1.0" encoding="gb2312"?>
<唐诗>
<五言绝句>
<作者 字号="太白">李白</作者>
<标题>静夜思</标题>
<内容>床前明月光,疑是地上霜。举头望明月,低头思故乡。</内容>
</五言绝句>
<五言绝句>
<作者 字号="太白">李太白</作者>
<标题>春晓</标题>
<内容>春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。</内容>
</五言绝句>
<五言绝句>
<作者 字号="季凌">王之涣</作者>
<标题>登鹤雀楼</标题>
<内容>白日依山尽,黄河入海流。欲穷千里目,更上一层楼</内容>
</五言绝句>
<五言绝句>
<作者>李清照</作者>
<标题>如梦令</标题>
<内容>昨夜风疏雨骤,浓睡不消残酒,试问卷帘人,却道海棠依旧,知否,知否,应是绿肥红瘦。</内容>
</五言绝句>
</唐诗>