asp.net教程-C#中使用XML——編寫XML

hbhuang發表於2007-10-20
在我的上一篇文章《C#中使用XML——讀取XML》中和大家討論瞭如何使用.NET Framework中提供的類在C#中讀取XML以及讀取的一些相關概念,那麼今天就說一說如何在C#中編寫XML文件,起初我覺得用程式設計的方式去編寫XML簡直就是自討苦吃,後來想想還是覺得挺有用的,我想Microsoft那班傢伙能編出這些類來應該不是僅僅為了向比爾i蓋茨交差吧!至於它的用處嘛……比如說做安裝程式啊!我們可以根據在安裝過程中使用者所選的選項以及一些設定來生成相應的XML文件再根據XML文件來初始化我們的應用程式。空洞的話不說那麼多了,下面我們來了解一下具體的實現細節。[@more@]
要編寫XML同樣是採用流的概念,在.NET中編寫XML的細節是作為XmlWriter類來實現的,但該類是抽象類不能夠例項化,為此,我們要想在程式中訪問它的方法以實現編寫XML的願望,必需使用它的派生類XmlTextWriter,該類提供了一系列的屬性和方法為我們編寫XML做準備,下面將詳細的介紹這個類:

構造函式

public XmlTextWriter(TextWriter);

public XmlTextWriter(Stream, Encoding);

public XmlTextWriter(string, Encoding);

第一個建構函式是把現有的TextWriter例項傳遞過去,System.IO.TextWriter類是一個有序的字元流

第二個建構函式是把要寫入的流作為第一個引數,第二個引數是指定XML文件的編碼方式,預設是UTF8,可取Encoding的列舉值,流可以是FileStream,MemoryStream,NetworkStream等等

第三個建構函式是把希望寫入的檔名當作一個字串(如果存在,就重寫該檔案)傳遞給第一個引數,第二個引數指定編碼方式



常用的方法:

WriterStartDocument()和WriterEndDocument()方法:

第一個方法用來編寫XML宣告部分,如:

第二個方法用來關閉任何開啟的元素或屬性並將編寫器重新設定為 Start 狀態。



WriterStartElement()和WriteEndElement()方法:

第一個方法用來寫出指定的開始標記,該方法有以下幾個過載:

WriterStartElement(string localname)

使用傳遞的字串作為元素的本地名稱

WriterStartElement(string localname,string namespace)

第一個引數指定元素的本地名稱,第二個引數指定元素所在的名稱空間

WriterStartElement(string prefix,string localname,string namespace)

第一個引數指定元素的字首,第二個引數指定元素的本地名稱,第三個引數指定元素所在的名稱空間

第二個方法用來寫出與開始元素對應的關閉元素,如果開始元素不包含任何內容,將用一個”/>”做為關閉元素



WriterStartAttribute()和WriterEndAttribute()方法:

第一個方法用於編寫一個屬性的開頭,該方法有兩個過載:

WriterStartAttribute(string localname,string namespace)

第一個引數指定屬性的本地名稱,第二個引數指定屬性所在的名稱空間

WriterStartAttribute(string prefix,string localname,string namespace)

第一個引數指定屬性的字首,第二個引數指定屬性的本地名稱,第三個引數指定屬性所在的名稱空間

第二個方法用於關閉WriterStartAttribute建立的屬性



WriterElementString()方法:

該方法可以建立一個包含字串值的元素,它有以下過載:

WriterElementString(string localname,string value)

如果編寫這樣的程式碼:WriterElementString(“para”,”Some text”) 將輸出:Some text

WriterElementString(string localname,string namespace,string value)

如果編寫這樣的程式碼:WriterElementString(“para”,””,”Some text”) 將輸出:Some text

如果編寫巢狀幾級的元素可使用WriterStartElement()和WriterEndElement()方法,如果編寫直接包含內容的元素可以使用該方法



WriterAttributeString()方法:

類似與WriterElementString()方法,在使用上如果屬性的值當中不包含實體可直接使用該方法來寫出屬性,如果屬性值包含實體可使用WriterStartAttribute()和WriterEndAttribute()方法,例如要寫出這樣的XML——,可編寫以下程式碼:

WriterStartElement(“para”);

WriterStartAttribute(“author”,null);

WriterString(“Do”);

WriterCharEntiry(“~n”);

WriterString(“a”);

WriterCharEntiry(“&”);

WriterString(“L.Perez”);

WriterEndAttribute();

WriterEndElement();

該方法有以下過載:

WriterAttributeString(string localname,string value);

WriterAttributeString(string localname,string namespace,string value);

WriterAttributeString(string prefx, string localname,string namespace,string value);



WriterNode(XmlReader reader,bool defattr)方法:

該方法可以從XmlReader讀取器中複製節點並把它們寫入XmlWriter流中,第一個引數是XmlReader的例項,第二個引數接受一個布林值,決定是否複製元素中的屬性,考慮下面XML片段:





TheXmlWriterclass writes XML content to a Stream.





以下程式碼複製其中的片段,reader代表XmlReader的例項writer代表XmlWriter類的例項:

while(reader.Read())

{

if (reader.Name == ”sent” && reader.NodeType == XmlNodeType.Element)

{

writer.WriterNode(reader,true);

}

}

得到以下輸出:



TheXmlWriterclass writes XML content to a Stream.





WriterComment(string text)方法:用於寫出註釋

WriterString(string text)方法:用於寫出文字

WriterCData(string text)方法:寫出CDATA資料塊

WriterBase64(byte[] buffer,int index,int count)方法:將指定的二進位制位元組編碼為 Base64 並寫出結果文字

Flush():將緩衝區中的所有內容重新整理到基礎流,並同時重新整理基礎流

Close():關閉此流和基礎流



以上對XmlTextWriter類的一些重要方法做了簡單介紹,下面我們就來看一個例程,看看在程式中如何使用這些方法,照樣還是先來看下執行效果圖:


Example1按紐將向一個檔案寫出XML宣告和一個元素節點以及節點內的文字,Example2按紐將在Example1的基礎上新增屬性節點,巢狀元素以及文字,WriteNode按紐使用WriterNode()方法在現有讀取器中複製該讀取器中的所有元素及屬性並寫到一個新的XML文件中,Example3按紐將寫一份完整的XML文件,Example4按紐在Example3按紐的基礎上另外生成一份文件並向該文件中追加CDATA部分,Example5按紐將使用WriterBase64()方法對一幅圖片進行編碼並將編碼後的資料寫到XML文件中,Example6按紐將使用Example5按紐中生成的XML讀取其中資料並對其中編碼資料進行解碼最後生成一張圖片。

以下是功能實現程式碼:


namespace XMLWriting

{

using System;

using System.IO;

using System.Text;

using System.Xml;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;



///

/// Form1 的摘要說明。

///


public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.TextBox textBox1;

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Button button3;

private System.Windows.Forms.Button button4;

private System.Windows.Forms.Button button5;

private System.Windows.Forms.Button button6;

private System.Windows.Forms.Button button7;

///

/// 必需的設計器變數。

///


private System.ComponentModel.Container components = null;



public Form1()

{

//

// Windows 窗體設計器支援所必需的

//

InitializeComponent();



//

// TODO: 在 InitializeComponent 呼叫後新增任何建構函式程式碼

//

}



///

/// 清理所有正在使用的資源。

///


protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}



#region Windows 窗體設計器生成的程式碼

///

/// 設計器支援所需的方法 - 不要使用程式碼編輯器修改

/// 此方法的內容。

///


private void InitializeComponent()

{

this.textBox1 = new System.Windows.Forms.TextBox();

this.button1 = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.button3 = new System.Windows.Forms.Button();

this.button4 = new System.Windows.Forms.Button();

this.button5 = new System.Windows.Forms.Button();

this.button6 = new System.Windows.Forms.Button();

this.button7 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// textBox1

//

this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)

| System.Windows.Forms.AnchorStyles.Left)

| System.Windows.Forms.AnchorStyles.Right)));

this.textBox1.Location = new System.Drawing.Point(0, 8);

this.textBox1.Multiline = true;

this.textBox1.Name = "textBox1";

this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;

this.textBox1.Size = new System.Drawing.Size(784, 332);

this.textBox1.TabIndex = 0;

this.textBox1.Text = "";

//

// button1

//

this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));

this.button1.Location = new System.Drawing.Point(0, 344);

this.button1.Name = "button1";

this.button1.TabIndex = 1;

this.button1.Text = "Example1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// button2

//

this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));

this.button2.Location = new System.Drawing.Point(88, 344);

this.button2.Name = "button2";

this.button2.TabIndex = 2;

this.button2.Text = "Example2";

this.button2.Click += new System.EventHandler(this.button2_Click);

//

// button3

//

this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));

this.button3.Location = new System.Drawing.Point(176, 344);

this.button3.Name = "button3";

this.button3.TabIndex = 3;

this.button3.Text = "WriteNode";

this.button3.Click += new System.EventHandler(this.button3_Click);

//

// button4

//

this.button4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));

this.button4.Location = new System.Drawing.Point(264, 344);

this.button4.Name = "button4";

this.button4.TabIndex = 4;

this.button4.Text = "Example3";

this.button4.Click += new System.EventHandler(this.button4_Click);

//

// button5

//

this.button5.Location = new System.Drawing.Point(352, 344);

this.button5.Name = "button5";

this.button5.TabIndex = 5;

this.button5.Text = "Example4";

this.button5.Click += new System.EventHandler(this.button5_Click);

//

// button6

//

this.button6.Location = new System.Drawing.Point(440, 344);

this.button6.Name = "button6";

this.button6.TabIndex = 6;

this.button6.Text = "Example5";

this.button6.Click += new System.EventHandler(this.button6_Click);

//

// button7

//

this.button7.Location = new System.Drawing.Point(528, 344);

this.button7.Name = "button7";

this.button7.TabIndex = 7;

this.button7.Text = "Example6";

this.button7.Click += new System.EventHandler(this.button7_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

this.ClientSize = new System.Drawing.Size(784, 373);

this.Controls.Add(this.button7);

this.Controls.Add(this.button6);

this.Controls.Add(this.button5);

this.Controls.Add(this.button4);

this.Controls.Add(this.button3);

this.Controls.Add(this.button2);

this.Controls.Add(this.button1);

this.Controls.Add(this.textBox1);

this.Name = "Form1";

this.Text = "XMLWriting";

this.ResumeLayout(false);



}

#endregion



///

/// 應用程式的主入口點。

///


[STAThread]

static void Main()

{

Application.Run(new Form1());

}



private void button1_Click(object sender, System.EventArgs e)

{

this.textBox1.Text = string.Empty;

const string fileName = "WriteXml.xml";



XmlTextWriter xmlTxtWt = new XmlTextWriter(fileName,Encoding.UTF8);



// 寫XML文件宣告

xmlTxtWt.WriteStartDocument();

// 寫XML起始元素

xmlTxtWt.WriteStartElement("ct","ContactDetails",");

// 寫文字

xmlTxtWt.WriteString("This is a XML file");

// 寫XML結束元素

xmlTxtWt.WriteEndElement();

// 寫關閉文件元素

xmlTxtWt.WriteEndDocument();



xmlTxtWt.Flush(); //重新整理

xmlTxtWt.Close();



this.textBox1.Text = ReadXml(fileName);

}



///

/// 讀取經過編寫的XML檔案的所有內容

///


/// 檔案路徑

/// 表示內容的字串

private string ReadXml(string xmlPath)

{

string xmlStr = string.Empty;

XmlTextReader xmlTxtRd = new XmlTextReader(xmlPath);



xmlTxtRd.MoveToContent();

xmlStr = xmlTxtRd.ReadOuterXml();



xmlTxtRd.Close();

return xmlStr;

}



private void button2_Click(object sender, System.EventArgs e)

{

this.textBox1.Text = string.Empty;

const string fileName = "WriteXml1.xml";



XmlTextWriter xmlTxtWt = new XmlTextWriter(fileName,Encoding.UTF8);



// 設定XML的輸出格式,這裡使用縮排

xmlTxtWt.Formatting = Formatting.Indented;

// 設定縮排的數量,這裡是4個空格,IndentChar屬性預設是空格

xmlTxtWt.Indentation = 4;



xmlTxtWt.WriteStartDocument();

xmlTxtWt.WriteStartElement("ct","ContactDetails",");

xmlTxtWt.WriteAttributeString("Date","20050121 14:00");

xmlTxtWt.WriteElementString("contact","abcd");

xmlTxtWt.WriteElementString("contact","efgh");

xmlTxtWt.WriteElementString("contact","ijkl");

xmlTxtWt.WriteElementString("contact","mnop");

xmlTxtWt.WriteEndElement();

xmlTxtWt.WriteEndDocument();



xmlTxtWt.Flush();

xmlTxtWt.Close();



this.textBox1.Text = ReadXml(fileName);

}



// 從讀取器中複製節點及其內容

private void button3_Click(object sender, System.EventArgs e)

{

XmlTextReader xmlTxtRd = new XmlTextReader("唐詩.xml");

XmlTextWriter xmlTxtWt = new XmlTextWriter("WriteXml2.xml",Encoding.UTF8);



xmlTxtWt.Formatting = Formatting.Indented;

xmlTxtWt.Indentation = 4;

xmlTxtWt.WriteStartDocument();

xmlTxtWt.WriteComment("以下是從讀取器中複製的節點");



try

{

while(xmlTxtRd.Read())

{

if (xmlTxtRd.NodeType == XmlNodeType.Element)

xmlTxtWt.WriteNode(xmlTxtRd,true);

}

}

catch(Exception exp)

{

MessageBox.Show(exp.ToString());

}

finally

{

xmlTxtWt.Flush();

xmlTxtWt.Close();

xmlTxtRd.Close();

}



this.textBox1.Text = ReadXml("WriteXml2.xml");

}



// 編寫一份完整的XML

private void button4_Click(object sender, System.EventArgs e)

{

this.textBox1.Text = string.Empty;

string fileName = "WriteXml3.xml";



XmlTextWriter xmlTxtWt = new XmlTextWriter(fileName,Encoding.UTF8);



xmlTxtWt.Formatting = Formatting.Indented;

xmlTxtWt.Indentation = 4;



xmlTxtWt.WriteStartDocument();

xmlTxtWt.WriteStartElement("ct","ContactDetails",");

xmlTxtWt.WriteAttributeString("Date","20050121 16:00");

xmlTxtWt.WriteComment("This document contains contact information.");

xmlTxtWt.WriteStartElement("contact");

xmlTxtWt.WriteAttributeString("title",string.Empty);

xmlTxtWt.WriteStartElement("name");

xmlTxtWt.WriteElementString("firstname","Steven");

xmlTxtWt.WriteElementString("middle",string.Empty);

xmlTxtWt.WriteElementString("lastname","LivingStone-Perez");

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteEndDocument();



xmlTxtWt.Flush();

xmlTxtWt.Close();



this.textBox1.Text = ReadXml(fileName);

}



// 新增CDATA資料塊

private void button5_Click(object sender, System.EventArgs e)

{

this.textBox1.Text = string.Empty;

string fileName = "WriteXml4.xml";



XmlTextWriter xmlTxtWt = new XmlTextWriter(fileName,Encoding.UTF8);



xmlTxtWt.Formatting = Formatting.Indented;

xmlTxtWt.Indentation = 4;



xmlTxtWt.WriteStartDocument();

xmlTxtWt.WriteStartElement("ct","ContactDetails",");

xmlTxtWt.WriteAttributeString("Date","20050121 16:00");

xmlTxtWt.WriteComment("This document contains contact information.");

xmlTxtWt.WriteStartElement("contact");

xmlTxtWt.WriteAttributeString("title",string.Empty);

xmlTxtWt.WriteStartElement("name");

xmlTxtWt.WriteElementString("firstname","Steven");

xmlTxtWt.WriteElementString("middle",string.Empty);

xmlTxtWt.WriteElementString("lastname","LivingStone-Perez");

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteStartElement("notes","); // 該節點的名稱空間與上面一樣,該節點將使用上面的字首

xmlTxtWt.WriteCData("88hshshhhdd8*^&@^*^#*&!%~~~(ghj*(**&%^){}^(*&7*(9$%###$@!");

xmlTxtWt.WriteEndElement();

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteFullEndElement();

xmlTxtWt.WriteEndDocument();



xmlTxtWt.Flush();

xmlTxtWt.Close();



this.textBox1.Text = ReadXml(fileName);

}



// 對圖片進行編碼,並寫出

private void button6_Click(object sender, System.EventArgs e)

{

int readByte = 0;

int bytesToRead = 100;

string fileName = "WriteXml5.xml";

this.textBox1.Text = string.Empty;



// 開啟圖片檔案,利用該圖片構造一個檔案流

FileStream fs = new FileStream(@"D:3.jpg",FileMode.Open);

// 使用檔案流構造一個二進位制讀取器將基後設資料讀作二進位制值

BinaryReader br = new BinaryReader(fs);



XmlTextWriter xmlTxtWt = new XmlTextWriter(fileName,Encoding.UTF8);

xmlTxtWt.Formatting = Formatting.Indented;

xmlTxtWt.Indentation = 4;



xmlTxtWt.WriteStartDocument();

xmlTxtWt.WriteStartElement("ct","ContactDetails",");

xmlTxtWt.WriteStartElement("image");

xmlTxtWt.WriteAttributeString("imageName","03.jpg");



byte[] base64buffer = new byte[bytesToRead];

do

{

readByte = br.Read(base64buffer,0,bytesToRead); //將資料讀入位元組陣列

xmlTxtWt.WriteBase64(base64buffer,0,readByte); //將陣列中二進位制值編碼為Base64並寫出到XML檔案

}while(bytesToRead <= readByte);



xmlTxtWt.WriteEndElement();

xmlTxtWt.WriteEndElement();

xmlTxtWt.WriteEndDocument();



xmlTxtWt.Flush();

xmlTxtWt.Close();



this.textBox1.Text = ReadXml(fileName);

}



// 解碼並生成圖片

private void button7_Click(object sender, System.EventArgs e)

{

int readByte = 0;

int bytesToRead = 100;



XmlTextReader xmlTxtRd = new XmlTextReader("WriteXml5.xml");



FileStream fs = new FileStream("newimage.jpg",FileMode.Create);

BinaryWriter bw = new BinaryWriter(fs);



byte[] base64buffer = new byte[bytesToRead];



while(xmlTxtRd.Read())

{

if (xmlTxtRd.NodeType == XmlNodeType.Element && xmlTxtRd.Name == "image")

{

do

{

readByte = xmlTxtRd.ReadBase64(base64buffer,0,bytesToRead);

bw.Write(base64buffer,0,readByte);

}while(readByte <= bytesToRead);

}

}



bw.Flush();

bw.Close();

fs.Close();



xmlTxtRd.Close();

}

}

}

以下是在WriteNode按紐中要使用到的XML檔案:

唐詩.xml







李白作者>

靜夜思標題>

床前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。內容>

五言絕句>



李太白作者>

春曉標題>

春眠不覺曉,處處聞啼鳥。夜來風雨聲,花落知多少。內容>

五言絕句>



王之渙作者>

登鶴雀樓標題>

白日依山盡,黃河入海流。欲窮千里目,更上一層樓內容>

五言絕句>



李清照作者>

如夢令標題>

昨夜風疏雨驟,濃睡不消殘酒,試問卷簾人,卻道海棠依舊,知否,知否,應是綠肥紅瘦。內容>

五言絕句>

唐詩>

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10291852/viewspace-977670/,如需轉載,請註明出處,否則將追究法律責任。

相關文章