Создание деревьев XML в C# (LINQ to XML)
В этой статье содержатся сведения о создании деревьев XML в C#.
Сведения об использовании результатов запросов 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, но потому что они не используются для функциональной конструкции, они не перечислены здесь.
Конструктор | Description |
---|---|
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>
Пример. Создание XElement с помощью XAttribute
Если передать экземпляр класса 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