# LOSoMan的C# XML資料讀存講解(C#為主) ###### tags: `LOSo講解` `C#` `XML` ## 什麼是XML? XML為可延伸標記式語言,可用來傳送與攜帶資料資訊。那麼,XML跟HTML有什麼差別呢? * XML著重在內容 * HTML強調布局 而且,他們的格式寫法及用法也稍微不同: 1. XML的元素名稱有分大小寫。HTML的標籤不分大小寫。 2. XML的元素一定都要有起始標籤和結尾標籤。而HTML的元素在某些情況下,可以不寫結尾標籤。 3. XML空元素需要在右箭號前面加一個斜線(如 <example/>)。然而,HTML只用一個單獨的起始標籤即可,沒有終結的斜線。 4. XML元素視空白為內容的一部分,除非特別明講,否則會予以保留。但在HTML中,大部分的元素都會拋棄多餘的空白,當瀏覽器在排定內容的格式時,會予以斷行。 XML是以 SGML 的格式精簡後制定出來的,其也靡補了 HTML 的不完美。XML是用來制定新的標準、用來定義一種新的標記語言,並無取代 HTML。可以說 XML 比 HTML 更適合做為資料的存取結構。 ## XML資料結構 首先,我們要搞懂XML裡的術語名詞: 1. 處理器(Processor)與應用(application): XML處理器(Processor,也稱作XML parser)分析標記式語言並傳遞結構化資訊給應用程式(application)。 2. 標記(Markup)與內容(content): XML文件的字元分為標記(Markup)與內容(content)兩類。標記通常以"<"開頭,以">"結尾,非標記的字元即為內容。 3. 標籤(Tag): tag屬於標記結構,以"<"開頭,以">"結尾。tag內不可有奇特符號字元([請參考](https://zh.wikipedia.org/zh-tw/XML)),tag可分為start-tag、end-tag、empty-element-tag三種不同形式。 start-tag,如:`<section>` end-tag,如:`</section>` empty-element-tag,如:`<line-break />` 4. 元素(Element): 元素是文件邏輯組成,或者在start-tag與匹配的end-tag之間,或者僅作為一個empty-element tag。如:`<greeting>Hello, world!</greeting>`的有內容element;或是`<line-break />`的empty element。 5. 屬性(Attribute): 屬性是一種標記結構,在start-tag或empty-element tag內部的「名字-值對」。如:`<img src="madonna.jpg" alt="Madonna" />`。每個元素可以有多個不重複的屬性,而每個屬性可以有一個值。 6. XML 聲明(declaration): XML文件如果以XML declaration開始,則表述了文件的一些資訊。如 `<?xml version="1.0" encoding="UTF-8"?>` ### 結構範例 ```xml=1 <?xml version="1.0"?> <農場> <山羊>小楊</山羊> <獼猴>小侯</獼猴> <農場名>好不開心農場 </農場名> </農場> ``` ## C#程式類別及方法 欲使用XML類別及方法,須先加入參考`using System.Xml;` 其常使用的相關類別有: 1. [XmlDocument](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmldocument.-ctor?view=net-6.0): 初始化 XmlDocument 類別的新執行個體。 * [XmlDocument.CreateXmlDeclaration(String, String, String)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmldocument.createxmldeclaration?view=net-6.0): 建立具有指定值的 XmlDeclaration 節點。 * [CreateElement(String)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmldocument.createelement?view=net-6.0): 建立具有指定名稱的項目。 * [AppendChild(XmlNode)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmlnode.appendchild?view=net-6.0#system-xml-xmlnode-appendchild(system-xml-xmlnode)): 將指定的節點加入這個節點之子節點清單的結尾。(注意: 此方法位於XmlNode類別,因為XmlDocument繼承了它) * [Save(String)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmldocument.save?view=net-6.0): 將 XML 文件儲存至指定的檔案。 如果指定的檔案存在,則這個方法會覆寫該檔案。 2. [XmlDeclaration](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmldeclaration?view=net-6.0): 代表 XML 宣告節點 <?xml version='1.0'...?>。 3. [XmlElement](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmlelement?view=net-6.0): 代表項目。 * [AppendChild(XmlNode)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmlnode.appendchild?view=net-6.0#system-xml-xmlnode-appendchild(system-xml-xmlnode)): 將指定的節點加入這個節點之子節點清單的結尾。(注意: 此方法位於XmlNode類別,因為XmlDocument繼承了它) * [SetAttribute(String, String)](https://docs.microsoft.com/zh-tw/dotnet/api/system.xml.xmlelement.setattribute?view=net-6.0): 設定具有指定名稱之屬性的值。 ## 程式範例 寫入XML部分程式(方法): ```csharp=1 public void SaveCurrentDatas(string path) //將現有的數據存成檔案 { if (File.Exists(path)) //當檔案已存在時,先刪除檔案 { File.Delete(path); } FileStream file = File.Create(path); //建立檔案 file.Close(); // 先關閉檔案(不關閉會導致XmlDocument無法存檔) XmlDocument doc = new XmlDocument(); //宣告一個XML文件 XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null); //建立XML檔的抬頭 XmlElement root = doc.CreateElement("Root"); //建立Root子項目 XmlElement school = doc.CreateElement("Header"); //建立Header子項目 for (int x = 0; x < header.Count; x++) { school.SetAttribute(header[x], x.ToString()); //Header子項目的屬性 } doc.AppendChild(xmlDeclaration); //將XML檔的抬頭加入文件 root.AppendChild(school); //將Header子項目加入Root下面 XmlElement data = doc.CreateElement("Data"); //建立Data子項目 for (int x = 0; x < datas.Count - 1; x++) //將每一列的資訊轉變成XML結構,並加入Data項目下 { if (datas[x][0] != string.Empty) { XmlElement singleRow = doc.CreateElement(datas[x][0]); Dictionary<int, string> dr = datas[x]; for (int y = 0; y < dr.Count; y++) { singleRow.SetAttribute(header[y], dr[y]); } data.AppendChild(singleRow); } } root.AppendChild(data); //將Data子項目加入Root下面 doc.AppendChild(root); //將Root子項目加入文件 doc.Save(path); //文件存檔 } ``` 讀取XML部分程式(方法): ```csharp=1 public bool ReadFileAsData(string path, DataGridView dgv) //將檔案讀成程式數據顯示於UI介面 { if (File.Exists(path)) { dgv.Rows.Clear(); //先清除DGV裡的所有列 using (XmlReader reader = XmlReader.Create(path)) //使用XML讀取器逐一讀取資訊 { while (reader.Read()) //XML讀取器讀取時 { if (reader.NodeType.Equals(XmlNodeType.Element)) { switch (reader.Name) { case "Root": break; case "Header": //當讀到Header子項目時進行之動作 dgv.ColumnCount = reader.AttributeCount; for (int atb = 0; atb < reader.AttributeCount; atb++) { reader.MoveToAttribute(atb); dgv.Columns[atb].HeaderText = reader.Name; } break; case "Data": //當讀到Data子項目時進行之動作 int count = 0; while (reader.Read()) { if (reader.AttributeCount > 0) { DataGridViewRow row = new DataGridViewRow(); row.HeaderCell.Value = count.ToString(); for (int atb = 0; atb < reader.AttributeCount; atb++) { reader.MoveToAttribute(atb); row.Cells.Add(new DataGridViewTextBoxCell { Value = reader.Value }); } dgv.Rows.AddRange(row); } } break; } } } } } return true; } ``` ### Demo結果 1. 存成XML檔: (UI介面的參數存成XML) 當我們開啟程式,並執行時畫面如下:  而我們輸入了一些資料:  設定路徑,並且存成檔案後,將檔案開啟,可以看到所存成的XML格式如下:  2. 開啟XML檔: (將XML檔變成程式參數顯示在UI介面) 點選"讀取"按鈕,選擇檔案後便可以開啟檔案(注意: 檔案必須符合可開啟格式)  ## 參考資料 1. [XML-維基百科,自由的百科全書](https://zh.wikipedia.org/zh-tw/XML) 2. [Microsoft XML 入門](https://support.microsoft.com/zh-tw/office/xml-%E5%85%A5%E9%96%80-a87d234d-4c2e-4409-9cbc-45e4eb857d44#bm6) 3. [XML與HTML差異比較整理筆記| Sun Soft Note - 點部落](https://dotblogs.com.tw/SunnyLearning/2017/08/10/164703) 4. [XML 與HTML 的關係](http://yes.nctu.edu.tw/Lecture/NewTech/C05_NewEra/XML/IntroXML/chapter2.html)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up