# 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
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.