节点阅读器
XML阅读器提供一种增量式的方法(一个一个节点的读)来处理文档的内容。到目前为止,我们假设源文件是一个基于硬盘的流或者是一个字符串流,然而,我们不能保证在实际中会提供一个源文件的XMLDOM对象给我们。在这种情况下,我们需要一个带有特别的读方法的特别的类。对这种情况,.net Framework提供了XmlNodeReader类。
就像XmlTextReader访问指定XML流中所有节点一样,XmlNodeReader类访问XMLDOM子树的所有节点。XMLDOM类(在.NET Framework中的XmlDocument类)支持基于Xpath的方法,例如SelectNodes方法和SelectSingleNode方法。这些方法的作用是把匹配的节点放在内存中。如果你需要处理子树中的所有节点,节点阅读器比用增量式方法处理节点的阅读器具有更高的效率:
// xmldomNode is the XML DOM node
XmlNodeReader nodeReader = new XmlNodeReader(xmldomNode);
while (nodeReader.Read())
{
// Do something here
}
当你要在配置文件(例如Web.cofig文件)中引用自定义的数据时,先把这些数据填充到XMLDOM树中,然后用XmlNodeReader类与XMLDOM类结合处理这些数据。这也是高效的。
用在本节中的方法创建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("");
foreach(string s in theArray) {
sb.Append("
sb.Append(s);
sb.Append(""/>");
}
sb.Append("");
代码通过循环取出数据中的元素,写好标签文本并把它们累加到一个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没有提供这种方法。
XMLTextWriter类