在 C# 中建立 XML 樹狀結構 (LINQ to XML)
本文提供在 C# 中建立 XML 樹狀結構的資訊。
如需使用 LINQ 查詢的結果作為 XElement 內容的資訊,請參閱功能建構。
建構元素
XElement 和 XAttribute 建構函式的簽章可讓您傳遞項目或屬性的內容,當做建構函式的引數。 由於其中一個建構函式採用多個引數,因此,您可以傳遞任何數目的子項目。 當然,這些子項目中的每個子項目都可以包含其自己的子項目。 對於任何項目,您可以加入任何數目的屬性。
加入 XNode (包括 XElement) 或 XAttribute 物件時,如果新內容沒有父代,這些物件只會附加到 XML 樹狀結構。 如果新內容已經成為父代,或是其他 XML 樹狀的一部分,則會複製新內容,而且新複製的內容會附加到 XML 樹狀。 本文中的最後一個範例會示範這個情況。
若要建立 contacts
XElement,您可以使用下列程式碼:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
如果縮排正確,建構 XElement 物件的程式碼會非常接近基礎 XML 的結構。
XElement 建構函式
XElement 類別會將下列建構函式用於功能結構。 請注意,XElement 還有一些其他建構函式,但由於不會用於功能建構,因此未在此處列出。
建構函式 | 描述 |
---|---|
XElement(XName name, object content) |
建立 XElement。 name 參數會指定項目的名稱;content 會指定項目的內容。 |
XElement(XName name) |
在將其 XElement 初始化為指定之名稱的情況下,建立 XName。 |
XElement(XName name, params object[] content) |
在將其 XElement 初始化為指定之名稱的情況下,建立 XName。 系統會從參數清單的內容建立屬性和/或子項目。 |
content
參數非常有彈性。 它支援屬於 XElement 有效子系的任何物件類型。 下列規則適用於傳入此參數的不同型別物件:
- 字串當做文字內容加入。
- XElement 當做子項目加入。
- XAttribute 當做屬性加入。
- XProcessingInstruction, XComment 或 XText 當做子內容加入。
- 系統會列舉 IEnumerable,並將這些規則遞迴地套用到結果。
- 若是其他任何型別,則會呼叫其
ToString
方法,並將結果當做文字內容加入。
範例:建立包含內容的 XElement
您可以建立包含具有單一方法呼叫之簡單內容的 XElement。 如果要這樣做,請將內容指定為第二個參數,如下所示:
XElement n = new XElement("Customer", "Adventure Works");
Console.WriteLine(n);
這個範例會產生下列輸出:
<Customer>Adventure Works</Customer>
您可以傳遞任何型別的物件當做內容。 例如,下列程式碼會建立包含浮點數的項目當做內容:
XElement n = new XElement("Cost", 324.50);
Console.WriteLine(n);
這個範例會產生下列輸出:
<Cost>324.5</Cost>
浮點數為 Boxed 而且會傳入建構函式。 Boxed 數字會轉換為字串,並當做項目的內容使用。
範例:建立包含一個子項目的 XElement
如果您要針對內容引數傳遞 XElement 類別的執行個體,建構函式會建立包含子項目的項目:
XElement shippingUnit = new XElement("ShippingUnit",
new XElement("Cost", 324.50)
);
Console.WriteLine(shippingUnit);
這個範例會產生下列輸出:
<ShippingUnit>
<Cost>324.5</Cost>
</ShippingUnit>
範例:建立包含多個子項目的 XElement
您可以針對內容傳入多個 XElement 物件。 每個 XElement 物件都會當做子項目包含在內。
XElement address = new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
);
Console.WriteLine(address);
這個範例會產生下列輸出:
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
藉由擴充前一個範例,您就可以建立整個 XML 樹狀結構,如下所示:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Console.WriteLine(contacts);
這個範例會產生下列輸出:
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
範例:建立具有 XAttribute 的 XElement
如果您針對內容引數傳遞 XAttribute 類別的執行個體,建構函式會建立具有屬性的元素:
XElement phone = new XElement("Phone",
new XAttribute("Type", "Home"),
"555-555-5555");
Console.WriteLine(phone);
這個範例會產生下列輸出:
<Phone Type="Home">555-555-5555</Phone>
範例:建立空元素
若要建立空的 XElement,請勿將任何內容傳遞至建構函式。 下列範例會建立空項目:
XElement n = new XElement("Customer");
Console.WriteLine(n);
這個範例會產生下列輸出:
<Customer />
範例:附加與複製的比較
如先前所述,加入 XNode (包括 XElement) 或 XAttribute 物件時,如果新內容沒有父代,這些物件只會附加到 XML 樹狀。 如果新內容已經成為父代,或是其他 XML 樹狀的一部分,則會複製新內容,而且新複製的內容會附加到 XML 樹狀。
下列範例示範將父元素新增至樹狀結構時的行為,以及將沒有父系的元素新增至樹狀結構時的行為:
// Create a tree with a child element.
XElement xmlTree1 = new XElement("Root",
new XElement("Child1", 1)
);
// Create an element that's not parented.
XElement child2 = new XElement("Child2", 2);
// Create a tree and add Child1 and Child2 to it.
XElement xmlTree2 = new XElement("Root",
xmlTree1.Element("Child1"),
child2
);
// Compare Child1 identity.
Console.WriteLine("Child1 was {0}",
xmlTree1.Element("Child1") == xmlTree2.Element("Child1") ?
"attached" : "cloned");
// Compare Child2 identity.
Console.WriteLine("Child2 was {0}",
child2 == xmlTree2.Element("Child2") ?
"attached" : "cloned");
// This example produces the following output:
// Child1 was cloned
// Child2 was attached