在.NET Framework中轻松处理XML数据(四)

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

XmlTextWriter

       用在本节中的方法创建XML文档显然并不困难。多年以来,开发者都是通过在缓存在连接一些字符串,连接好以后再把缓存中字符串输出到文件的方式来创建XML文档。但是以这种方式创建XML文档的方法只有在你保证字符串中不存在任何细小的错误的时候才有效。.NET Framework通过用XMLwriter提供了更好的创建XML文档的方法。

       XML Writer类以只前(forward-only)的方式输出XML数据到流或者文件中。更重要的是,XML Writer在设计时就保证所有的XML数据都符合W3C XML 1.0推荐规范,你甚至不用担心忘记写闭标签,因为XML Writer会帮你写。XmlWriter是所有 XML writer的抽象基类。.NET Framework只提供唯一的一个writer ----XmlTextWriter类。

       我们先来看看XML writers和旧的writers的不同点,下面的代码保存了一个string型的数组:

StringBuilder sb = new StringBuilder("");

sb.Append("<array>");

foreach(string s in theArray) {

   sb.Append("<element value=/"");

   sb.Append(s);

   sb.Append("/"/>");

}

sb.Append("</array>");

       代码通过循环取出数据中的元素,写好标签文本并把它们累加到一个string中。代码保证输出的内容是格式良好的并且注意了新行的缩进,及支持命名空间。当创建的文档结构比较简单时,这种方法可能不会有错误。然而,当你要支持处理指令,命名空间,缩进,格式化以及实体的时候,代码的数量就成指数级增长,出错的可能性也随之增长。

       XML writer写方法功能对应每个可能的XML节点类型,它使创建xml文档的过程更符合逻辑、更少的信赖于繁琐的标记语言。图六演示了怎么样用XmlTextWriter类的方法来连接一个string数据。代码很简洁,用XML writer的代码更容易读、结构更好。

Figure 6 Serializing a String Array

void CreateXmlFileUsingWriters(String[] theArray, string filename)

{

    // Open the XML writer (用默认的字符集)

    XmlTextWriter xmlw = new XmlTextWriter(filename, null);

    xmlw.Formatting = Formatting.Indented;

 

    xmlw.WriteStartDocument();

    xmlw.WriteStartElement("array");

    foreach(string s in theArray)

    {

        xmlw.WriteStartElement("element");

        xmlw.WriteAttributeString("value", s);

        xmlw.WriteEndElement();

    }

    xmlw.WriteEndDocument();

 

    // Close the writer

    xmlw.Close();

}

       然而XML writer并不是魔术师----它不能修复输入的错误。XML writer不会检查元素名和属性名是否有效,也不保证被用的任何的Unicode字符集适合当前架构的编码集。如上所述,为了避免输出错误,必须要杜绝非XML字符。但是writer没有提供这种方法。

       另外,当创建一个属性节点时,Writer不会检验属性节点的名称是否与已存在的元素节点的名称相同。最后,XmlWriter类不是一个带验证的Writer类,也不保证输出是否符合schema或者DTD。在.NET Framework中带验证的writer类目前来说还没有提供。但是在我写的《Applied XML Programming for Microsoft .NET (Microsoft Press®, 2002)》书中,我自己写了一个带验证的Writer组件。你可以到下面的网址去下载源码:http://www.microsoft.com/MSPress/books/6235.asp.

       图七列出了XML writer的一些状态值(state)。这些值都源于WriteState枚举类。当你创建一个Writer,它的初始状态为Start,表示你将要配置该对象,实际上writer没有开始。下一个状态是Prolog,该状态是当你调用WriteStartDocument方法开始工作的时候设置的。然后,状态的转换就取决于你的写的文档及文档的内容了。Prolog状态一直保留到当你增加一个非元素节点时,例如注释元素,处理指令及文档类型。当第一个节点也就是根节点写完后,状态就变为Element。当你调用WriterStartAtribute方法时状态转换为Attribute,而不是当你调用WriteAtributeString方法写属性时转换为该状态。如果那样的话,状态应该是Element。当你写一个闭标签(>)时,状态会转换成Content。当你写完文档后,调用WriteEndDocument方法,状态就会返回为Start,直到你开始写另一个文档或者把Writer关掉。

Figure 7 States for XML Writer

State

Description

Attribute

The writer enters this state when an attribute is being written

Closed

The Close method has been called and the writer is no longer available for writing operations

Content

The writer enters this state when the content of a node is being written

Element

The writer enters this state when an element start tag is being written

Prolog

The writer is writing the prolog of a well-formed XML 1.0 document

Start

The writer is in an initial state, awaiting for a write call to be issued

Writer 把输出文本存在内部的一个缓冲区内。一般情况下,缓冲区会被刷新或者被清除,当Writer被关闭前XML文本应该要写出。在任何时你都可以通过调用Flush方法清空缓冲区,把当前的内容写到流中(通过BaseStream属性暴露流),然后释放部分占用的内存,Writer仍保持为打开状态(open  state),可以继续操作。注意,虽然写了部分的文档内容,但是在Writer没有关闭前其它的程序是不能处理该文档的。
    可以用两种方法来写属性节点。第一种方法是用WriteStartAtribute方法去创建一个新的属性节点,更新Writer的状态。接着用WriteString方法设置属性值。写完后,用WriteEndElement方法结束该节点。另外,你也可以用WriteAttributeString方法去创建新的属性节点,当writerr的状态为Element时,WriterAttributeString开始工作,它单独创建一个属性。同样的,WriteStartElement方法写节点的开始标签(<),然后你可以随意的设置节点的属性和文本内容。元素节点的闭标签都带”/ >”。如果想写闭标签可以用WriteFullEndElement方法来写。

应该避免传送给写方法的文本中包含敏感的标记字符,例如小于号(<)。用WriteRaw方法写入流的字符串不会被解析,我们可以用它来对xml文档写入特殊的字符串。下面的两行代码,第一行输出的是”&lt”,第二行输出”<”:

writer.WriteString("<");

writer.WriteRaw("<");

读写流

有趣的是,reader(阅读器)和writer类提供了基于Base64 和BinHex编码的读写数据流的方法。WriteBase64 和 WriteBinHex方法的功能与其它的写方法的功能存在着细微的差别。它们都是基于流的,这两个方法的功能像一个byte数组而不是一个string。下面的代码首先把一个string转换成一个byte数组,然后把它们写成一个Base64 编码流。Encoding类的GetBytes静态方法完成转换的任务:

writer.WriteBase64(

   Encoding.Unicode.GetBytes(buf),

   0, buf.Length*2);

图八中代码演示了把一个string数据转换为Base64 编码的XML流。图九是输出的结果。


Figure 8 Persisting a String Array as Base64

using System;

using System.Text;

using System.IO;

using System.Xml;

 

class MyBase64Array

{

    public static void Main(String[] args)

    {

        string outputFileName = "test64.xml";

        if (args.Length > 0)

            outputFileName = args[0];    // file name

 

        // 把数组转换成XML

        String[] theArray = {"Rome", "New York", "Sydney", "Stockholm",

                             "Paris"};

 

        CreateOutput(theArray, outputFileName);

        return;

    }

 

    private static void CreateOutput(string[] theArray, string filename)

    {

        // 打开XML writer

        XmlTextWriter xmlw = new XmlTextWriter(filename, null);

    //使子元素根据 IndentationIndentChar 设置缩进。此选项只对元素内容进行缩进

        xmlw.Formatting = Formatting.Indented;

    //书写版本为“1.0”的 XML 声明

        xmlw.WriteStartDocument();

    //写出包含指定文本的注释 <!--...-->。

        xmlw.WriteComment("Array to Base64 XML");

    //开始写出array节点

        xmlw.WriteStartElement("array");

//写出具有指定的前缀、本地名称、命名空间 URI 和值的属性

        xmlw.WriteAttributeString("xmlns", "x", null, "dinoe:msdn-mag");

    // 循环的写入array的子节点

            foreach(string s in theArray)

        {

        //写出指定的开始标记并将其与给定的命名空间和前缀关联起来

xmlw.WriteStartElement("x", "element", null);

//把S转换成byte[]数组, 并把byte[]数组编码为 Base64 并写出结果文本,要写入的字节数为s总长度的2倍,一个string占的字节数是2字节。

xmlw.WriteBase64(Encoding.Unicode.GetBytes(s), 0,               s.Length*2);  

//关闭子节点

            xmlw.WriteEndElement();

        }

    //关闭根节点,只有两级

        xmlw.WriteEndDocument();

 

        // 关闭writer

        xmlw.Close();

 

        // 读出写入的内容

        XmlTextReader reader = new XmlTextReader(filename);

        while(reader.Read())

        {

        //获取节点名为element的节点

            if (reader.LocalName == "element")

            {

       

                byte[] bytes = new byte[1000];

                int n = reader.ReadBase64(bytes, 0, 1000);

                string buf = Encoding.Unicode.GetString(bytes);

 

                Console.WriteLine(buf.Substring(0,n));

            }

        }

        reader.Close();

 

    }

}



Figure 9 String Array in Internet Explorer
    Reader
类有专门的解释Base64BinHex编码流的方法。下面的代码片断演示了怎么样用XmlTextReader类的ReadBase64方法解析用Base64BinHex编码集创建的文档。

XmlTextReader reader = new XmlTextReader(filename);

while(reader.Read()) {

  if (reader.LocalName == "element") {

    byte[] bytes = new byte[1000];

int n = reader.ReadBase64(bytes, 0, 1000);

string buf = Encoding.Unicode.GetString(bytes);

    Console.WriteLine(buf.Substring(0,n));

  }

}

reader.Close();

       byte型转换成string型是通过Encoding类的GetString方法实现的。尽管我只介绍了基于Base64编码集的代码,但是可以简单的用BinHex替换方法名就可以实现读基于BinHex编码的节点内容(用ReadBinHex方法)。这个技巧也可以用于读任何用byte数据形式表示的二进制数据,尤其是image类型的数据。
.NET Framework中使用C#轻松处理XML数据 无论是读取、写入还是修改XML文件,都可以通过XmlDocument类提在.NET Framework轻松处理XML数据 - 使用C#无论是读取、写入还是修改XML文件,通过XmlDocument类和相关方法,我们可以灵活地操作XML数据。要读取XML文件,我们可以使用.NET Framework提供的XmlDocument类。然后,我们获取XML的根节点,并修改第一个子节点的"Name"和"Age"元素的文本内容。方法创建XML声明。方法将XML文件保存到名为"data.xml"的文件中。 阅读详情

相关推荐

c#自定义XML配置文件解析 .Net Framework

1、重写.Net Framework中的ConfigurationSection 2、自定义SQL、Message两种类型配置工具 3、提供自定义配置文件工程;配置文件示例。

XML字符串Base64解码并获取XML中的数据

XML字符串Base64解码并获取XML中的数据

qq_54571327的博客 2146

MG-SOFT netconf browser2018免费版

MG-SOFT netconf browser免费版,请勿传播,仅供调试交流学习使用。 请注意需在linux下使用

.NET Framework轻松处理XML数据

.NET Framework轻松处理XML数据   前言 在.NET Framework中,XmlTextReader和XmlTextWriter类提供了对xml数据的读和写操作。在本文中,作者讲述了XML阅读器(Reader)的体系结构及它们怎样与XMLDOM 和SAX 解释器结合。作者也演示了怎么样运用阅读器分析和验证XML文档,怎么样创建格式良好的XML文档,以及怎么样用函数读/写基

随风自由 2631

.NET操作XML--XMLTextWriter

[c-sharp] view plaincopyprint? void CreateXMLFileUsingWriters(String[] theArray, string filename)       {       // Open the XML writer (用默认的字符集)       XMLTextWriter xmlw = new Xml

welkin_zxj 856

数据.Net使用OpenXml导出Excel

1、使用NuGet包管理器安装 DocumentFormat.OpenXml 2.调用导出方法 /// <summary> /// 导出Excel /// </summary> /// <param name="fileName">保存文件路径</param> /// <param name="exportTable">数据源</param> private static void Exp

ah_zjn的博客 2682

.NET使用Office Open XML导出大量数据到 Excel

我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EXCEL,但不久前,我在一个项目碰到一个需求:要将几个分别有近60多万的数据源导出到Excel中,我们先不要讨论这个需求本身是否合理,客户就是要这样。我先后用NPOI和EPPlus,都发现同一个问题:O...

weixin_30297281的博客 562

.NET Framework轻松处理XML数据()

 XmlTextWriter类 用在本节中的方法创建XML文档显然并不困难。多年以来,开发者都是通过在缓存在连接一些字符串,连接好以后再把缓存中字符串输出到文件的方式来创建XML文档。但是以这种方式创建XML文档的方法只有在你保证字符串中不存在任何细小的错误的时候才有效。.NET Framework通过用XMLwriter提供了更好的创建XML文档的方法。 XML Writer类以只前(f

杨义贤心灵驿站 531

C#中配置文件的读写xml

该文件是源于博主“net5i”,登录界面的用户名,密码信息获取并生成相应的XML文件,以及对XML文件的读取并显示出来,工程是C#读写XML配置文件的程序。由于运行时有点小问题,特在VS15中进行Clone了一个完整的工程,可以运行,感谢博主net5i的分享(http://download.csdn.net/download/net5i/890290),由于工程需要,正在学习中

转载:.NET Framework轻松处理XML数据()

 转载自:http://www.admin5.com/html/edu/Pro/xml/20061226/32120.htmlXmlTextWriter类    用在本节中的方法创建XML文档显然并不困难。多年以来,开发者都是通过在缓存在连接一些字符串,连接好以后再把缓存中字符串输出到文件的方式来创建 XML文档。但是以这种方式创建XML文档的方法只有在你保证字符串中不存在任何细小的错误的时候才有

prophet08的专栏 496

.NET Framework轻松处理XML数据()

本文假设你已熟悉XML.NET Framework       前言   在.NET Framework中,XmlTextReader和XmlTextWriter类提供了对xml数据的读和写操作。在本文中,作者讲述了XML阅读器(Reader)的体系结构及它们怎样与XMLDOM 和SAX 解释器结合。作者也演示了怎么样运用阅读器分析和验证XML文档,怎么样创建格式良好的XML文档,以及怎么样

chyich的专栏 1605

.NET Framework轻松处理XML数据()

分析属性值      大部分情况下,属性值都是一个简单的文本字符串。然而,这并不意味着实际应用中的属性值都是字符型的。有时候,属性值是由许多种类型的数据组合而成的,例如Date或Boolean,这时,你就要用XmlConvert或System.Convevt类的方法把这些类型转换成原来的类型。XmlConvert和System.Convevt类都能实现数据类型的转换,但是XmlConvert类依据

傲のBlog 1065

.NET Framework轻松处理XML数据()

.NET Framework中,XmlTextReader和XmlTextWriter类提供了对xml数据的读和写操作。在本文中,作者讲述了XML阅读器(Reader)的体系结构及它们怎样与XMLDOM 和SAX 解释器结合。作者也演示了怎么样运用阅读器分析和验证XML文档,怎么样创建格式良好的XML文档,以及怎么样用函数读/写基于Base64和BinHex编码的大型的XML文档。最后,作者讲了

杨义贤心灵驿站 610

NET Framework轻松处理XML数据(1)

.Net Framework中,XMLTextReader和XmlTextWriter类提供了对xml数据的读和写操作。在本文中,作者讲述了XML阅读器(Reader)的体系结构及它们怎样与XMLDOM和SAX解释器结合。作者也演示了怎么样运用阅读器分析和验证XML文档,怎么样创建格式良好的XML文档,以及怎么样用函数读/写基于Base64和BinHex编码的大型的XML文档。最后,作者讲了怎么

686
上一篇: 在.NET Framework中轻松处理XML数据(三)
下一篇: 在.NET Framework中轻松处理XML数据(五)
chyich
博客等级 码龄25年 3粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值