XmlReader 唯讀、XmlWriter 唯寫,兩者獨立運作。管理龐大 XML 文檔且需同時讀寫時,DOM 雖支援雙向操作但需全量載入記憶體,效能不佳。本文設計混合流分析器 XmlTextReadWriter,實現邊讀邊寫、選擇性修改。
使用 XmlReader 循序訪問源文檔節點,XmlWriter 同步創建節點拷貝。在拷貝過程中可:新增節點、忽略節點、編輯節點內容、修改屬性值。完成後以新文檔替換舊文檔。
XmlTextReader reader = new XmlTextReader(inputFile);
XmlTextWriter writer = new XmlTextWriter(outputFile);
writer.Formatting = Formatting.Indented;
reader.MoveToContent();
// 寫入根節點
writer.WriteStartElement(reader.LocalName);
// 讀取並輸出每個節點(示例:跳過偶數節點)
int i = 0;
while (reader.Read())
{
if (i % 2 == 1)
writer.WriteNode(reader, false);
i++;
}
writer.WriteEndElement();
writer.Close();
reader.Close();
不繼承 XmlReader/XmlWriter,而是內部封裝兩者。公開唯讀的 Reader/Writer 屬性供進階操作。
| 方法 | 功能 |
|---|---|
| AddAttributeChange | 快取節點屬性變更資訊,WriteAttributes 時批次提交 |
| Read | 內部 reader.Read 的簡單封裝 |
| WriteAttributes | 特製版 WriteAttributes,寫出節點所有屬性並套用快取變更 |
| WriteEndDocument | 終結文檔,關閉 reader 與 writer |
| WriteStartDocument | 初始化 writer,加入預設註解與 XML 序言 |
修改屬性必須先呼叫 AddAttributeChange 宣告,所有變更暫存於臨時表,最後呼叫 WriteAttributes 一次性提交並清除快取。
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
rw.Writer.WriteAttributes(rw.Reader, false); // 深層複製
if (rw.Reader.IsEmptyElement)
rw.Writer.WriteEndElement();
break;
}
}
rw.Writer.WriteEndElement(); // 關閉根標籤
rw.WriteEndDocument(); // 關閉文檔與資源
}