在 C# 中创建 XML 树 (LINQ to XML)Creating XML trees in C# (LINQ to XML)

本节提供有关使用 C# 来创建 XML 树的信息。This section provides information about creating XML trees in C#.

有关使用 LINQ 查询结果作为 XElement 内容的信息,请参阅功能构造 (LINQ to XML) (C#)For information about using the results of LINQ queries as the content for an XElement, see Functional Construction (LINQ to XML) (C#).

构造元素Constructing elements

通过 XElementXAttribute 构造函数的签名,可以将元素或属性的内容作为参数传递到构造函数。The signatures of the XElement and XAttribute constructors let you pass the contents of the element or attribute as arguments to the constructor. 由于其中一个构造函数使用可变数目的参数,因此可以传递任意数目的子元素。Because one of the constructors takes a variable number of arguments, you can pass any number of child elements. 当然,这些子元素中的每一个都可以包含它们自己的子元素。Of course, each of those child elements can contain their own child elements. 对任意元素,可以添加任意多个属性。For any element, you can add any number of attributes.

在添加 XNode(包括 XElement)或 XAttribute 对象时,如果新内容没有父级,则直接将这些对象附加到 XML 树中。When adding XNode (including XElement) or XAttribute objects, if the new content has no parent, the objects are simply attached to the XML tree. 如果新内容已经有父级,并且是另一 XML 树的一部分,则克隆新内容,并将新克隆的内容附加到 XML 树。If the new content already is parented, and is part of another XML tree, the new content is cloned, and the newly cloned content is attached to the XML tree. 本主题最后一个示例对此进行了演示。The last example in this topic demonstrates this.

若要创建 contactsXElement,可以使用下面的代码:To create a contactsXElement, you could use the following code:

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 的结构。If indented properly, the code to construct XElement objects closely resembles the structure of the underlying XML.

XElement 构造函数XElement constructors

XElement 类使用下面的构造函数用于函数构造。The XElement class uses the following constructors for functional construction. 请注意,对于 XElement,存在其他一些构造函数,但是由于它们不用于函数构造,因此没有在此列出。Note that there are some other constructors for XElement, but because they are not used for functional construction they are not listed here.

构造函数Constructor 说明Description
XElement(XName name, object content) 创建 XElementCreates an XElement. name 参数指定元素的名称;content 指定元素的内容。The name parameter specifies the name of the element; content specifies the content of the element.
XElement(XName name) 创建一个 XElement,其 XName 初始化为指定名称。Creates an XElement with its XName initialized to the specified name.
XElement(XName name, params object[] content) 创建一个 XElement,其 XName 初始化为指定名称。Creates an XElement with its XName initialized to the specified name. 从参数列表的内容创建属性和/或子元素。The attributes and/or child elements are created from the contents of the parameter list.

content 参数极其灵活。The content parameter is extremely flexible. 它支持作为 XElement 的有效子对象的任何类型的对象。It supports any type of object that is a valid child of an XElement. 下面的规则适用于在此参数中传递的不同类型的对象:The following rules apply to different types of objects passed in this parameter:

  • 字符串添加为文本内容。A string is added as text content.

  • XElement 添加为子元素。An XElement is added as a child element.

  • XAttribute 添加为属性。An XAttribute is added as an attribute.

  • XProcessingInstructionXCommentXText 添加为子内容。An XProcessingInstruction, XComment, or XText is added as child content.

  • 枚举 IEnumerable,并且这些规则递归应用于结果。An IEnumerable is enumerated, and these rules are applied recursively to the results.

  • 对任何其他类型,调用其 ToString 方法,结果添加为文本内容。For any other type, its ToString method is called and the result is added as text content.

创建包含内容的 XElementCreating an XElement with content

可以使用单个方法调用来创建一个包含简单内容的 XElementYou can create an XElement that contains simple content with a single method call. 为此,请指定内容作为第二个参数,如下所示:To do this, specify the content as the second parameter, as follows:

XElement n = new XElement("Customer", "Adventure Works");  
Console.WriteLine(n);  

该示例产生下面的输出:This example produces the following output:

<Customer>Adventure Works</Customer>  

可以将任意类型的对象作为内容进行传递。You can pass any type of object as the content. 例如,下面的代码创建一个包含浮点数作为内容的元素:For example, the following code creates an element that contains a floating point number as content:

XElement n = new XElement("Cost", 324.50);  
Console.WriteLine(n);  

该示例产生下面的输出:This example produces the following output:

<Cost>324.5</Cost>  

该浮点数被装箱并传递给构造函数。The floating point number is boxed and passed in to the constructor. 装箱的数字转换为字符串,然后用作元素的内容。The boxed number is converted to a string and used as the content of the element.

创建具有子元素的 XElementCreating an XElement with a child element

如果传递 XElement 类的一个实例作为内容参数,则构造函数将创建一个具有子元素的元素:If you pass an instance of the XElement class for the content argument, the constructor creates an element with a child element:

XElement shippingUnit = new XElement("ShippingUnit",  
    new XElement("Cost", 324.50)  
);  
Console.WriteLine(shippingUnit);  

该示例产生下面的输出:This example produces the following output:

<ShippingUnit>  
  <Cost>324.5</Cost>  
</ShippingUnit>  

创建具有多个子元素的 XElementCreating an XElement with multiple child elements

可以传递多个 XElement 对象作为内容。You can pass in a number of XElement objects for the content. 每个 XElement 对象都作为子元素包含进来。Each of the XElement objects is included as a child element.

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);  

该示例产生下面的输出:This example produces the following output:

<Address>  
  <Street1>123 Main St</Street1>  
  <City>Mercer Island</City>  
  <State>WA</State>  
  <Postal>68042</Postal>  
</Address>  

将上面的示例进行扩展,可以创建整个 XML 树,如下所示:By extending the above example, you can create an entire XML tree, as follows:

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);  

该示例产生下面的输出:This example produces the following output:

<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 的 XElementCreating an XElement with an XAttribute

如果传递 XAttribute 类的一个实例作为内容参数,则构造函数将创建一个具有属性的元素:If you pass an instance of the XAttribute class for the content argument, the constructor creates an element with an attribute:

XElement phone = new XElement("Phone",  
    new XAttribute("Type", "Home"),  
    "555-555-5555");  
Console.WriteLine(phone);  

该示例产生下面的输出:This example produces the following output:

<Phone Type="Home">555-555-5555</Phone>

创建空元素Creating an empty element

若要创建空 XElement,请不要将任何内容传递给构造函数。To create an empty XElement, you do not pass any content to the constructor. 下面的示例创建一个空元素:The following example creates an empty element:

XElement n = new XElement("Customer");  
Console.WriteLine(n);  

该示例产生下面的输出:This example produces the following output:

<Customer />  

附加与克隆Attaching vs. cloning

前面提到,在添加 XNode(包括 XElement)或 XAttribute 对象时,如果新内容没有父级,则直接将这些对象附加到 XML 树。As mentioned previously, when adding XNode (including XElement) or XAttribute objects, if the new content has no parent, the objects are simply attached to the XML tree. 如果新内容已经有父级,并且是另一 XML 树的一部分,则克隆新内容,并将新克隆的内容附加到 XML 树。If the new content already is parented and is part of another XML tree, the new content is cloned, and the newly cloned content is attached to the XML tree.

以下示例演示将有父级的元素添加到树中,以及将没有父级的元素添加到树中时的行为。The following example demonstrates the behavior when you add a parented element to a tree, and when you add an element with no parent to a tree.

// Create a tree with a child element.  
XElement xmlTree1 = new XElement("Root",  
    new XElement("Child1", 1)  
);  
  
// Create an element that is 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");  

// The example displays the following output:  
//    Child1 was cloned  
//    Child2 was attached  

请参阅See also