Одним из преимуществ использования LINQ to XML в C# является отсутствие необходимости использования префиксов XML. Когда LINQ to XML выполняет загрузку или синтаксический анализ XML-документа, каждый префикс XML соотносится с соответствующим пространством имен XML. После этого при работе с документом, в котором используются пространства имен, почти всегда можно оценить пространство имен при помощи URI-кода пространства имен, а не по префиксу. Когда разработчики работают с именами XML на LINQ to XML, они всегда работают с полностью выраженными именами XML (т. е. пространство имен XML и локальное имя). Однако при необходимости LINQ to XML позволяет управлять префиксами пространства имен и обрабатывать их.
При использовании LINQ to XML в сочетании с литералами Visual Basic XML необходимо использовать префиксы пространства имен при работе с документами в пространствах имен.
В LINQ to XML следующий класс представляет имена XML: XName. Имена XML часто появляются в API LINQ to XML, и, когда требуется использовать имя XML, обнаруживается параметр XName. Однако напрямую работать с XName приходится редко. XName содержит неявное преобразование строки.
Чтобы создать элемент или атрибут, находящийся в пространстве имен, необходимо сначала объявить и инициализировать объект XNamespace. Затем следует использовать перегруженный оператор сложения для объединения пространства имен с локальным именем, выраженным строкой.
В следующем примере создается документ с одним пространством имен. По умолчанию LINQ to XML сериализует документ с использованием пространства имен по умолчанию.
// Create an XML tree in a namespace.
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);
Этот пример выводит следующие данные.
xmlLang
<Root xmlns="http://www.adventure-works.com">
<Child>child content</Child>
</Root>
В следующем примере создается документ с одним пространством имен. Он также создает атрибут, который объявляет пространство имен с префиксом пространства имен. Создать атрибут, объявляющий пространство имен с префиксом, можно, указав имя атрибута в качестве префикса пространства имен и поместив его в пространство имен Xmlns. Значение этого атрибута представляет собой URI пространства имен.
// Create an XML tree in a namespace, with a specified prefix
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);
Этот пример выводит следующие данные.
xmlLang
<aw:Root xmlns:aw="http://www.adventure-works.com">
<aw:Child>child content</aw:Child>
</aw:Root>
Следующий пример иллюстрирует создание документа, содержащего два пространства имен. Одно из них — пространство имен по умолчанию. Другое — пространство имен с префиксом.
При включении атрибутов пространств имен в корневой элемент пространства имен сериализуются, так что http://www.adventure-works.com становится пространством имен по умолчанию, а www.fourthcoffee.com сериализуется с префиксом «fc». Чтобы создать атрибут, объявляющий применяемое по умолчанию пространство имен, необходимо создать атрибут с именем «xmlns» без пространства имен. Значение этого атрибута является используемым по умолчанию идентификатором URI пространства имен.
// The http://www.adventure-works.com namespace is forced to be the default namespace.
XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
new XAttribute("xmlns", "http://www.adventure-works.com"),
new XAttribute(XNamespace.Xmlns + "fc", "www.fourthcoffee.com"),
new XElement(fc + "Child",
new XElement(aw + "DifferentChild", "other content")
),
new XElement(aw + "Child2", "c2 content"),
new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);
Этот пример выводит следующие данные.
xmlLang
<Root xmlns="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">
<fc:Child>
<DifferentChild>other content</DifferentChild>
</fc:Child>
<Child2>c2 content</Child2>
<fc:Child3>c3 content</fc:Child3>
</Root>
В этом примере создается документ, который содержит два пространства имен с префиксами.
XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
new XAttribute(XNamespace.Xmlns + "aw", aw.NamespaceName),
new XAttribute(XNamespace.Xmlns + "fc", fc.NamespaceName),
new XElement(fc + "Child",
new XElement(aw + "DifferentChild", "other content")
),
new XElement(aw + "Child2", "c2 content"),
new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);
Этот пример выводит следующие данные.
xmlLang
<aw:Root xmlns:aw="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">
<fc:Child>
<aw:DifferentChild>other content</aw:DifferentChild>
</fc:Child>
<aw:Child2>c2 content</aw:Child2>
<fc:Child3>c3 content</fc:Child3>
</aw:Root>
Другой метод получения того же результата состоит в использовании развернутых имен вместо объявления и создания объекта XNamespace.
Этот подход влияет на производительность. Всякий раз при передаче LINQ to XML строки, содержащей развернутое имя, система должна проанализировать это имя, обнаружить атомизированное пространство имен и атомарное имя. Этот процесс требует затрат процессорного времени. Если производительность является важным фактором, целесообразнее объявить и использовать объект XNamespace явным образом.
Дополнительные сведения, касающиеся повышения производительности, см. в разделе Предварительная атомизация объектов XName (LINQ to XML).
// Create an XML tree in a namespace, with a specified prefix
XElement root = new XElement("{http://www.adventure-works.com}Root",
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
new XElement("{http://www.adventure-works.com}Child", "child content")
);
Console.WriteLine(root);
Этот пример выводит следующие данные.
xmlLang
<aw:Root xmlns:aw="http://www.adventure-works.com">
<aw:Child>child content</aw:Child>
</aw:Root>
Извлечения значения элемента
В этом разделе показано получение значений элементов. Это можно сделать двумя основными способами. Первый способ состоит в приведении XElement или XAttribute к желаемому типу. Оператор явного преобразования, который преобразует содержимое элемента или атрибута в указанный тип и присваивает полученное значение указанной переменной. Иначе можно использовать свойство XElement.Value или XAttribute.Value.
Однако при использовании C# приведение, как правило, является лучшим подходом. В частности, становится проще написание кода, обеспечивающего получение значения элемента или атрибута, который может существовать или не существовать, после приведения элемента (или атрибута) к типу, допускающему значение NULL. Это демонстрирует последний пример из данного раздела. Однако нельзя так задать содержимое элемента через приведение, как через свойство XElement.Value.
При использовании Visual Basic лучшим подходом является использование свойства XElement.Value.
Пример
Для получения значения элемента нужно просто привести объект XElement к желаемому типу. Всегда можно привести элемент к строке следующим образом.
XElement e = new XElement("StringElement", "abcde");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + (string)e);
Этот пример выводит следующие данные.
<StringElement>abcde</StringElement>
Value of e:abcde
Также можно приводить элементы к типам, отличным от строковых. Например, если имеется элемент, содержащий целое число, его можно привести к типу int, как показано в следующем коде.
XElement e = new XElement("Age", "44");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + (int)e);
Этот пример выводит следующие данные.
<Age>44</Age>
Value of e:44
LINQ to XML предусматривает операторы явного приведения для следующих типов данных: string, bool, bool?, int, int?, uint, uint?, long, long?, ulong, ulong?, float, float?, double, double?, decimal, decimal?, DateTime, DateTime?, TimeSpan, TimeSpan?, GUID и GUID?.
LINQ to XMLпредоставляет аналогичные операторы приведения для объектов XAttribute.
Свойство Value может использоваться для получения содержимого элемента.
XElement e = new XElement("StringElement", "abcde");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + e.Value);
Этот пример выводит следующие данные:
<StringElement>abcde</StringElement>
Value of e:abcde
Список литературы
1. Статья «Язык XML - Описание технологии». Взято с www.codenet.ru
2. Pro LINQ: Language Integrated Query in C# 2008 Joseph C. Rattz, Jr.
3. Статьи с http://msdn.microsoft.com
4. C# 2010: ускоренный курс для профессионалов, Трей Нэш
5. Статьи с www.wikipedia.org