如何格式化字符串的xml?

【问】xml的标准形式是:

<Root>

<Name>John</Name>

<Age>16</Age>

</Root>

现在假如是一个字符串的形式——

<Root><Name>John</Name><Age>16</Age></Root>

请教如何对该字符串格式化,以便成为标准的xml文件格式?

【错误回答】

直接使用XmlDocument的LoadXml方法,然后输出保存到一个新的xml文档中。

【正解】

XmlDocument是存储以及对xml文件操作的一个.NET基本类型。除了对xml进行增删改查之外还可以直接对xml文件进行格式化操作。XmlDocument其中自带一个方法“WriteTo”,该方法需要一个继承TextWriter类的子类。针对xml文件,应该选用XmlTextWriter;XmlTextWriter又需要一个StringWriter流,而StringWriter需要一个Stream对象。恰巧StringBuilder是实现了Stream抽象类的子类。因此可以被使用。代码如下:

[C#]

XmlDocument doc = new XmlDocument();
doc.LoadXml("<Root><Name>John</Name><Age>16</Age></Root>");
StringBuilder sub = new StringBuilder();
StringWriter sw = new StringWriter(sub);
XmlTextWriter xw = new XmlTextWriter(sw);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
Console.WriteLine(sub);

[VB.NET]

Dim doc As New XmlDocument()
doc.LoadXml("<Root><Name>John</Name><Age>16</Age></Root>")
Dim [sub] As New StringBuilder()
Dim sw As New StringWriter([sub])
Dim xw As New XmlTextWriter(sw)
xw.Formatting = Formatting.Indented
doc.WriteTo(xw)
Console.WriteLine([sub])

值得注意的是:您必须设置XmlTextWriter的Formatting格式为Indented(锯齿,自动缩进的意思),否则仍然无法实现效果。

【总结】

1 首先声明一个StringBuilder对象,作为目标源。

2 其次声明一个StringWriter,作为连接该对象的“管道”(字符串“写入流”)。

3)然后声明一个XmlTextWriter,连接StringWriter(把StringWriter作为参数传入),并设置Formatting格式为Indented

4)最后通过XmlDocumentWriteTo方法连接到XmlTextWriter即可。

【拓展】

关于“Stream”,“Reader/Writer”的“IO”探讨

众所周知,System.IO命名空间里边包括了大量支持文件、内存、网络、字符串等流写入(出)的类以及旗下方法。其主要从几个抽象类派生而成:

1)Stream:该类主要用作目标对象。一般地,微软这方面命名是:“目标对象”+Stream——

文件流:FileStream。

内存流:MemoryStream。

网络流:NetWorkStream(值得注意的是有一个类是位于System.NET.Sockets,专门用Socket或者TCP/IP等通讯发送信息时用)。

2) TextWriter:该类用于执行“写”操作,写入到指定某个继承Stream类的子类。这方面微软有对应的类:

                文件、内存、网络流写入:StreamWriter。

                字符串流写入:StringWriter(注意:其需要一个StringBuilder,而不是需要一个Stream子类对象作为参数)。

                Xml文件流写入:XmlWriter和XmlTextWriter,前者自身是一个抽象类(不是继承TextWriter),单独也可以使用(使用Create方法,支持Stream和StringBuilder等),简单实现一些非常简单基本的xml读写操作(主要针对字符串格式的),后者继承了XmlWriter(构造函数参数支持对Stream和TextWriter子类进行写入),实现了其中所有的abstract方法,能够读写复杂的数据类型,如CData等)。同时还支持Formatting格式化,就像上面的例子。

不过有意思的在于:凡是以上类(以Writer结尾的),要写入到目标中的话必须显式调用Close或者Flush方法,否则这是驻留在内存中,不会真正写入到目标的。这也就是为什么很多时候程序没有错误,目标总是得不到的原因。

3) TextReader:该类用于执行“读”操作,读入到指定某个继承Stream类的子类。这方面微软有对应的类:

                文件、内存、网络流读入:StreamReader。

                字符串流读入:StringReader(注意:其需要一个string对象,而不是需要一个Stream子类对象作为参数)。

            Xml文件流读入:XmlReader和XmlTextReader,前者自身是一个抽象类(不是继承TextReader),单独也可以使用(使用Create方法,支持TextReader和Stream等),简单实现一些非常简单基本的xml读写操作(主要针对字符串格式的),后者继承了XmlWriter,实现了其中所有的abstract方法,能够读写复杂的数据类型等)。

posted @ 2012-01-10 14:35  Serviceboy  阅读(2017)  评论(0编辑  收藏  举报