2011年4月21日 星期四

C# XML 應用


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
// 建立一個 XmlDocument 物件並加入 Declaration
XmlDocument xdoc = new XmlDocument();
xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"));
XmlDocument xdoc1 = new XmlDocument();

// 建立根節點物件並加入 XmlDocument 中 (第 0 層)
XmlElement rootElement = xdoc.CreateElement("Employees");
xdoc.AppendChild(rootElement);

// 建立一個子元素, 並在這個子元素裡加上一個 attribute (第 1 層)
XmlElement eleChild1 = xdoc.CreateElement("Employee");
XmlAttribute attChild1 = xdoc.CreateAttribute("Department");
attChild1.Value = "研發部";
eleChild1.Attributes.Append(attChild1);
rootElement.AppendChild(eleChild1);

// 再為這個子元素加入一個孫元素 (第 2 層)
XmlElement eleGrandChild1 = xdoc.CreateElement("Name");
eleGrandChild1.InnerText = "吳大寶";
eleChild1.AppendChild(eleGrandChild1);

// 建立第二個子元素 (第 1 層)
XmlElement eleChild2 = xdoc.CreateElement("Employee");
XmlAttribute attChild2 = xdoc.CreateAttribute("Department");
attChild2.Value = "總務部";
eleChild2.Attributes.Append(attChild2);

// 建立第二個孫元素 (第 2 層)
XmlElement eleGrandChild2 = xdoc.CreateElement("Name");
eleGrandChild2.InnerText = "鄭小胖";
eleChild2.AppendChild(eleGrandChild2);
rootElement.AppendChild(eleChild2);

// 將建立的 XML 節點儲存為檔案
xdoc.Save(System.AppDomain.CurrentDomain.BaseDirectory +"Test01.xml" );
Console.Write("XML created!");
/*
上面程式的寫法很直接, 你對照產生出來的 XML 內容就自然看得懂程式的邏輯了。
* 唯一值得注意的一點是, 無論是 XmlElement 或 XmlAttribute 物件都一律是 reference type
* , 一旦被建立起來, 那麼不管你把它附加到哪裡幾次
* , 都不會自動建立新的副本 (instance)。
* 例如, 當你建立好上例中第一個子元素後, 雖然你已把它加入根節點
* , 但你不能再把同一個子元素賦予新值或加入不同的孫節點後
* , 再重複加入根節點。就算你這麼做, 根節點中也不會因此產生兩個子節點
* (原因已經說過了 - 程式並不會因為 Append 指令而為你自動產生新的副本)。
* 因此在程式中, 我建立了不同 ID 的子節點、attribute 和孫節點。
*/


/*Linq 方式 創建XML*/
XDocument xdoc12 = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("Employees", new XElement("Employee", new XAttribute("Department", "研發部"), new XElement("Name", "吳大寶")), new XElement("Employee", new XAttribute("Department", "總務部"), new XElement("Name", "鄭小胖"))));
xdoc.Save(System.AppDomain.CurrentDomain.BaseDirectory + "Test02.xml");
Console.Write("XML created!");

/*讀取XML*/
//XmlDocument xdoc3 = new XmlDocument();
//xdoc.Load(System.AppDomain.CurrentDomain.BaseDirectory+"Test01.xml" );

/*如果 XML 文件的來源不是檔案而是字串, 該怎麼讀入呢? 這時我們可以使用 MemoryStream 物件, 如下例:*/
//Stream s = new MemoryStream(Encoding.UTF8.GetBytes(@" 吳大寶 21 鄭小胖 25 "));
//XmlReader reader = XmlTextReader.Create(s);
//XElement ele = XElement.Load(reader);


/*巡覽XML*/
XmlDocument xdoc4 = new XmlDocument();
xdoc.Load(System.AppDomain.CurrentDomain.BaseDirectory+"Test02.xml");
navigate(xdoc.DocumentElement); // 傳入根節點

Console.ReadKey();


/*相對於 XmlDocument 物件的巡覽方式,
* LINQ 的巡覽方式非常的不一樣。若使用 LINQ, 你根本不必寫什麼遞迴程式 (也很難寫得出來; 我試過了)
* , 重點是根本沒有需要。LINQ 的主要價值,
* 在於它提供了對不同資料來源 (包括 Database、文字資料、XML 與 Object 等等) 的相同的資料篩選方式。
* 對 LINQ to XML 而言, 你不需使用遞迴程式就能簡單的以 XDocument.Descendants
* 或 XElement.Descendants 來把根節點和所有子節點一次通通列出來。
* 以下我們來看看如何列出範例 XML 文件裡面所有的資料:*/

XDocument xdoc5= XDocument.Load(System.AppDomain.CurrentDomain.BaseDirectory+"Test02.xml");
var eles = from ele in xdoc5.Descendants()
where ele.Name.LocalName == "Employee"
select new
{
//att = (string)ele.Attribute("Department"),
att = ele.Attribute("Department"),
name = (string)ele.Element("Name")
};
foreach (var ele in eles)
Console.Write("Department = " + ele.att + ", Name = " + ele.name + Environment.NewLine);
Console.ReadKey();

IEnumerable eles1 = xdoc5.Element("Employees").Elements("Employee");
foreach (XElement ele in eles1)
Console.Write(ele.Name + " = " + ele.Value + Environment.NewLine);
Console.ReadKey();
}

static void navigate(XmlNode node)
{
if (node.NodeType == XmlNodeType.Text) // 如果是文字節點則直接印出
Console.WriteLine(node.InnerText + "");
else // 如果是一般節點則另外處理
{
Console.Write("<" + node.Name); if (node.Attributes != null) // 如果是 attribute 則逐個印出 foreach (XmlAttribute attr in node.Attributes) Console.Write(" " + attr.Name + " = \"" + attr.Value + "\""); Console.Write(">");
//核心的部份, 而其中最關鍵的就在以下這段:
foreach (XmlNode child in node.ChildNodes) // 如果還有子節點則繼續處理
navigate(child);
Console.WriteLine("");
}
}
}
}

沒有留言:

張貼留言