在 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>
该浮点数被装箱并传递给构造函数。 装箱的数字转换为字符串,然后用作元素的内容。
示例:创建具有子元素的 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