Figure 10 Using the WriteNode Method
XMLTextReader reader = new X
mlTextReader(inputFile);
XmlTextWriter writer = new XMLTextWriter(outputFile);
// 配置 reader 和 writer
writer.Formatting = Formatting.Indented;
reader.MoveToContent();
// Write根節點
writer.WriteStartElement(reader.LocalName);
// Read and output every other node
int i=0;
while(reader.Read())
{
if (i % 2)
writer.WriteNode(reader, false);
i++;
}
// Close the root
writer.WriteEndElement();
// Close reader and writer
writer.Close();
reader.Close();
我的XmlTextReadWriter類並沒有從XmlReader或者XMLWriter類中繼承。取而代之的是另外兩個類,一個是基於只讀流(stream)的操作類,另一個是基於只寫流
的操作類。XMLTextReadWriter類的方法用Reader對象讀數據,寫入到Writer對象。為了適應不同的需求,內部的Reader和Writer 對象分別通過只讀的Reader和Writer屬性公開。圖十一列出了該類的一些方法:
Figure 11 XMLTextReadWriter Class Methods
Method
Description
AddAttributeChange
Caches all the information needed to perform a change on a node attribute. All the changes cached through this method are processed during a successive call to WriteAttributes.
Read
Simple wrapper around the internal reader's Read method.
WriteAttributes
Specialized version of the writer's WriteAttributes method, writes out all the attributes for the given node, taking into account all the changes cached through the AddAttributeChange method.
WriteEndDocument
Terminates the current document in the writer and closes both the reader and the writer.
WriteStartDocument
Prepares the internal writer to output the document and add a default comment text and the standard XML prolog.
這個新類有一個Read方法,它是對Reader的read方法的一個簡單的封裝。另外,它提供了WriterStartDocument和WriteEndDocument方法。它們分別初始化
/釋放(finalize)了內部Reader和writer對象,還處理所有I/O操作。在循環讀節點的同時,我們就可以直接的修改節點。出於性能的原因,要修改屬性必須先用AddAttributeChange方法聲明。對一個節點的屬性所作的所有修改都會存放在一個臨時的表中,最後,通過調用WriteAttribute方法提交修改,清除臨時表。
圖十二所示的代碼演示了客戶端用XmlTextReadWriter類在讀操作的同時修改屬性值的優勢。在本期的msdn中提供了XMLTextReadWriter類的C#和VB源代碼下載(見本文開頭提供的鏈接)。
Figure 12 Changing Attribute Values
private void ApplyChanges(string nodeName, string attribName,
string oldVal, string newVal)
{
XmlTextReadWriter rw = new XMLTextReadWriter(InputFileName.Text,
OutputFileName.Text);
rw.WriteStartDocument(true, CommentText.Text);
// 手工修改根節點
rw.Writer.WriteStartElement(rw.Reader.LocalName);
// 開始修改屬性
// (可以修改更多節點的屬性)
rw.AddAttributeChange(nodeName, attribName, oldVal, newVal);
// 循環處理文檔
while(rw.Read())
{
switch(rw.NodeType)
{
case XMLNodeType.Element:
rw.Writer.WriteStartElement(rw.Reader.LocalName);
if (nodeName == rw.Reader.LocalName)
// 修改屬性
; rw.WriteAttributes(nodeName);
else
// deep copy
rw.Writer.WriteAttributes(rw.Reader, false);
if (rw.Reader.IsEmptyElement)
rw.Writer.WriteEndElement();
break;
}
}
// Close the root tag
rw.Writer.WriteEndElement();
// Close the document and any internal resources
rw.WriteEndDocument();
}
XmlTextReadWriter類不僅可以讀XML文檔,也可以寫XML文檔。你可以它來讀XML文檔的內容,如果需要,你還可以用它來做一些基本的更新操作。基本的更新操作在這裡是指修改某個已存在的屬性的值或者某個節點的內容,又或者是增加一個新的屬性或節點。對於更復雜的操作,最好還是用XMLDOM分析器。
總結
Reader和Writer是.Net Framework中處理XML數據的根本。它們提供了對所有XML數據訪問功能的原始的API。Reader像
一個新的分析器類,它即有XMLDOM的強大,又有SAX的快速簡單。Writer為簡單的創建XML文檔而設計。雖然Reader和Writer都是.Net Framework中的一小塊,但是它們是相互獨立的API。在本文中,我們只討論了怎麼樣用Reader和Writer完成一些主要的工作, 介紹了驗證分析器的原理機制,並把Reader和writer整合在一個單獨的類中。上述所有的這些類都是輕量級的,類似於游標式的XMLDOM分析器。