XML Writer
表示一个编写器,该编写器提供一种快速、非缓存和只进的方式来生成包含 XML 数据的流或文件。
命名空间: System.Xml
程序集: System.Xml(在 System.Xml.dll 中)
语法
--------------------------------------------------------------------------------
public abstract class XmlWriter : IDisposable
备注
--------------------------------------------------------------------------------
XmlWriter 类支持 W3C 可扩展标记语言 (XML) 1.0 和"XML 中的命名空间"建议。
说明:
来创建 XmlWriter 对象。
注意 使用 XmlWriter 方法输出 XML 时,在调用 Close 方法前,不会写入元素和属性。
安全注意事项
当使用 XmlWriter 类时需要考虑下列事项。
XmlWriter 引发的异常可能会泄漏您不希望冒泡到应用程序的路径信息。应用程序必须捕捉并适当处理这些异常。
XmlWriter 不验证任何传递到 WriteDocType 或 WriteRaw 方法的数据。您不应将任意数据传递给这些方法。
示例
--------------------------------------------------------------------------------
下面的示例在流中导航以确定当前节点类型,然后使用 XmlWriter 输出 XmlReader 内容。
StringBuilder output = new StringBuilder();
String xmlString =
@"<?xml version='1.0'?>
<!-- This is a sample XML document -->
<Items>
<Item>test with a child element <more/> stuff</Item>
</Items>";
// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
XmlWriterSettings ws = new XmlWriterSettings();
ws.Indent = true;
using (XmlWriter writer = XmlWriter.Create(output, ws))
{
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(reader.Name);
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}
}
}
OutputTextBlock.Text = output.ToString();
继承层次结构
--------------------------------------------------------------------------------
System.Object
System.Xml.XmlWriter
System.Xml.XmlDictionaryWriter
**************************************************************************************
此代码主要演示了如何使用XmlWriter来填充XML树,同时也顺带示范了如何使用XslCompiledTransform按照指定的样式表将XML从一个格式转换成另外一个新的格式。
示例代码
使用XDocument.CreateWriter()方法将会创建一个XmlWriter,随后向这个XmlWriter写入的任何内容都会被写入的XDocument表示的XML树中,这是关键点。另外使用XDocument.CreateReader()则可以创建一个XmlReader,然后使用此读取器就可以读取内存中XML树中的内容了。这两个方法一个创建了写入器,一个创建了读取器。
代码中是使用XslCompiledTransform类来转换XML文档的,这可以通过它的XslCompiledTransform.Transform()方法完成,而在调用此方法之前,应该确保已经通过调用XslCompiledTransform.Load()方法加载了样式表。不然,要让它如何给你转换呢?^_^
view source
print?
string XslMarkup = @"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1>
<xsl:value-of select='Child1'/>
</C1>
<C2>
<xsl:value-of select='Child2'/>
</C2>
</Root>
</xsl:template>
</xsl:stylesheet>";
XDocument SourceTree = new XDocument(
new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")));
XDocument NewTree = new XDocument();
using (XmlWriter Writer = NewTree.CreateWriter())
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(XslMarkup)));
xslt.Transform(SourceTree.CreateReader(),
Writer);
}
Console.WriteLine(NewTree);
代码中所创建的原始的XML树内容是这样的:
view source
print?
<Parent>
<Child1>Child1 data</Child1>
<Child2>Child2 data</Child2>
</Parent>
转换后的内容则是这样的:
view source
print?
<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>
这说明了什么呢?说明已经被转换了嘛!-_-
**************************************************************************************
填充 XML 树的一种方式是使用 CreateWriter 创建一个 XmlWriter,然后写入 XmlWriter。XML 树将用写入到 XmlWriter 的所有节点进行填充。
在与预期会向 XmlWriter 写入数据的另一个类(如 XslCompiledTransform)一起使用 LINQ to XML 时,通常应使用此方法。
CreateWriter 可能在调用 XSLT 转换时使用。本示例创建一个 XML 树,从该 XML 树创建一个 XmlReader,创建一个新文档,然后创建要写入到新文档的 XmlWriter。示例然后调用 XSLT 转换,传入 XmlReader 和 XmlWriter。在转换成功完成后,将使用转换结果填充新的 XML 树。
string xslMarkup = @"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1>
<xsl:value-of select='Child1'/>
</C1>
<C2>
<xsl:value-of select='Child2'/>
</C2>
</Root>
</xsl:template>
</xsl:stylesheet>";
XDocument xmlTree = new XDocument(
new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")
)
);
XDocument newTree = new XDocument();
using (XmlWriter writer = newTree.CreateWriter())
{
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));
// Execute the transformation and output the results to a writer.
xslt.Transform(xmlTree.CreateReader(), writer);
}
Console.WriteLine(newTree);
此示例产生以下输出:
<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>
******************************************************************************************
XmlTextWriter类可以把XML写入一个流、文件或TextWriter对象中。与XmlTextReader一样,XmlTextWriter类以只向前、未缓存的方式进行写入。XmlTextWriter的可配置性很高,可以指定是否缩进文本、缩进量、在属性值中使用什么引号以及是否支持命名空间等信息。
下面是一个简单的示例,说明了如何使用XmlTextWriter类,这段代码在XMLWriterSample1文件夹中:
private void button1_Click(object sender, System.EventArgs e)
{
// change to match your path structure
string fileFTEL="..\\..\\..\\booknew.xml";
// create the XmlTextWriter
XmlTextWriter tw=new XmlTextWriter(fileName,null);
// set the formatting to indented
tw.Formatting=Formatting.Indented;
tw.WriteStartDocument();
// Start creating elements and attributes
tw.WriteStartElement("book");
tw.WriteAttributeString("genre","Mystery");
tw.WriteAttributeString("publicationdate","2001");
tw.WriteAttributeString("ISBN","123456789");
tw.WriteElementString("title","The Case of the Missing Cookie");
tw.WriteStartElement("author");
tw.WriteElementString("name","Cookie Monster");
tw.WriteEndElement();
tw.WriteElementString("price","9.99");
tw.WriteEndElement();
tw.WriteEndDocument();
//clean up
tw.Flush();
tw.Close();
}
这里编写一个新的XML文件booknew.xml,并给一本新书添加数据。注意XmlTextWriter会用新文件重写旧文件。本章的后面会把一个新元素或节点插入到现有的文档中,使用FileStream对象作为参数,实例化XmlTextWriter对象。还可以把一个带有文件名和路径的字符串或者一个基于TextWriter的对象作为参数。接着,设置Indenting属性,之后,子节点就会自动从父节点缩进。WriteStartDocument()会添加文档声明。下面开始写入数据。首先是book元素,添加genre、publicationdate 和 ISBN属性。然后写入title、author和price元素,注意author元素有一个子元素名。
单击按钮,生成booknew.xml文件:
<?xml version="1.0"?>
<book genre="Mystery" publicationdate="2001" ISBN="123456789">
<title>The Case of the Missing Cookie</title>
<author>
<name>Cookie Monster</name>
</author>
<price>9.99</price>
</book>
在开始和结束写入元素和属性时,要注意控制元素的嵌套。在给authors元素添加name子元素时,就可以看到这种嵌套。注意WriteStartElement()和 WriteEndElement()方法调用是如何安排的,以及它们是如何在输出文件中生成嵌套的元素的。
除了WriteElementString ()和 WriteAttributeString()方法外,还有其他几个专用的写入方法。WriteCData()可以输出一个Cdata部分(<!CDATA[…])>),把要写入的文本作为一个参数。WriteComment()以正确的XML格式写入注释。WriteChars()写入字符缓冲区的内容,其工作方式类似于前面的ReadChars(),它们都使用相同类型的参数。WriteChar()需要一个缓冲区(一个字符数组)、写入的起始位置(一个整数)和要写入的字符个数(一个整数)。
使用基于XmlReader 和 XmlWriter的类读写XML是非常灵活的,使用起来也很简单。下面介绍如何使用System.Xml命名空间中XmlDocument 和 XmlNode类执行DOM。