- •А.А. Волосевич
- •1. Работа с Числами
- •2. Дата и время
- •3. Работа со строками и текстом
- •4. Преобразование информации
- •5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •7. Перечислители и итераторы
- •8. Интерфейсы стандартных коллекций
- •9. Массивы и класс system.Array
- •10. Типы для работы с коллекциями-списками
- •11. Типы для работы с коллекциями-множествами
- •12. Типы для работы с коллекциями-словарями
- •13. Типы для создания пользовательских коллекций
- •14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •15. Работа с объектами файЛовой системы
- •16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •17. Основы xml
- •18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имён xml
- •19. ДОполнительные возможности обработки xml
- •20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •21. Состав и взаимодействие сборок
- •22. Метаданные и получение информации о типах
- •23. Позднее связывание и кодогенерация
- •24. Динамические типы
- •25. Атрибуты
- •26. Файлы конфигуРации
- •27. Основы мНогопоточноГо программирования
- •28. Синхронизация потоков
- •29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •30. Асинхронный вызов методов
- •31. Процессы и домены
- •32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •33. Диагностика
Запросы, модификация и трансформация xml
Рассмотрим набор методов и свойств, используемых в LINQ to XML при выборке данных. Класс XObject имеет свойство NodeType для типа XML-узла и свойство Parent, указывающее, какому элементу принадлежит узел.
Методы классов XNode и XContainer позволяют получить у элемента наборы предков и дочерних узлов (элементов). При этом возможно указание фильтра – имени элемента. Большинство методов возвращают коллекции, реализующие IEnumerable1.
// методы выборки у XNode
public IEnumerable<XElement> Ancestors(); // + XName name
public IEnumerable<XElement> ElementsAfterSelf(); // + XName name
public IEnumerable<XElement> ElementsBeforeSelf(); // + XName name
public bool IsAfter(XNode node);
public bool IsBefore(XNode node);
public IEnumerable<XNode> NodesAfterSelf();
public IEnumerable<XNode> NodesBeforeSelf();
// методы выборки у XContainer
public IEnumerable<XNode> DescendantNodes();
public IEnumerable<XElement> Descendants(); // + XName name
public XElement Element(XName name);
public IEnumerable<XElement> Elements(); // + XName name
Класс XDocument позволяет получить корневой элемент при помощи свойства Root. В классе XElement есть методы для запроса элементов-предков и элементов-потомков, а также методы для запроса атрибутов.
// методы выборки у XElement
public IEnumerable<XElement> AncestorsAndSelf(); // + XName name
public XAttribute Attribute(XName name);
public IEnumerable<XAttribute> Attributes(); // + XName name
public IEnumerable<XNode> DescendantNodesAndSelf();
public IEnumerable<XElement> DescendantsAndSelf(); // + XName name
Статический класс Extensions определяет несколько методов расширения, работающих с коллекциями элементов или узлов XML:
IEnumerable<XElement> Ancestors<T>(...) where T: XNode;
IEnumerable<XElement> AncestorsAndSelf(...);
IEnumerable<XAttribute> Attributes(...);
IEnumerable<XNode> DescendantNodes<T>(...) where T: XContainer;
IEnumerable<XNode> DescendantNodesAndSelf(...);
IEnumerable<XElement> Descendants<T>(...) where T: XContainer;
IEnumerable<XElement> DescendantsAndSelf(...);
IEnumerable<XElement> Elements<T>(...) where T: XContainer;
IEnumerable<T> InDocumentOrder<T>(...) where T: XNode;
IEnumerable<XNode> Nodes<T>(...) where T: XContainer;
void Remove(this IEnumerable<XAttribute> source);
void Remove<T>(this IEnumerable<T> source) where T: XNode;
Продемонстрируем примеры запросов, используя файл planets.xml с описанием четырёх планет. Загрузим файл и выведем имена планет:
var xml = XDocument.Load("planets.xml");
var query = xml.Root.Elements("planet").Select(p =>
p.Element("name").Value);
foreach (var x in query) Console.WriteLine(x);
Выберем все элементы с именем moon, которые являются потомками корневого элемента. У каждого из полученных элементов возьмём первого ребёнка с именем name:
var moons = xml.Descendants("moon").Select(p => p.Element("name"));
Найдём элемент, содержащий указанный текст:
var phobos = xml.DescendantNodes().OfType<XText>()
.Where(t => t.Value == "Phobos")
.Select(t => t.Parent);
Модификация XML-информации в памяти выполняется при помощи следующих методов классов XNode, XContainer, XElement:1
// методы модификации у XNode
public void AddAfterSelf(object content); // + params
public void AddBeforeSelf(object content); // + params
public void Remove();
public void ReplaceWith(object content); // + params
// методы модификации у XContainer
public void Add(object content); // + params
public void AddFirst(object content); // + params
public void RemoveNodes();
public void ReplaceNodes(object content); // + params
// методы модификации у XElement
public void RemoveAll();
public void RemoveAttributes();
public void ReplaceAll(object content); // + params
public void ReplaceAttributes(object content); // + params
public void SetAttributeValue(XName name, object value);
public void SetElementValue(XName name, object value);
Рассмотрим несколько примеров модификации XML. Начнём с удаления заданных узлов. Для этого используем метод расширения Remove<T>():
var xml = XDocument.Load("planets.xml");
xml.Element("planets").Elements("planet").Elements("moon").Remove();
Продемонстрируем добавление и замену элементов:
var p = XDocument.Load("planets.xml").Root;
p.Add(new XElement("planet", new XElement("name", "Jupiter")));
var moon = p.Descendants("moon").First();
moon.ReplaceWith(new XElement("DeathStar"));
Покажем добавление атрибута к элементу:
XElement sun = xml.Element("planets");
sun.Add(new XAttribute("MassOfSun", "332.946 Earths"));
Функциональные конструкторы и поддержка методами выборки коллекций открывают богатые возможности трансформации наборов объектов в XML. В следующем примере показано создание XML-документа на основе коллекции студентов gr (см. параграф 2.14):
var xml = new XElement("students",
from student in gr
select new XElement("student",
new XAttribute("name", student.Name),
new XAttribute("age", student.Age),
from mark in student.Marks
select new XElement("mark", mark)));
Хотя предыдущий пример использует отложенный оператор Select(), полная итерация по набору выполняется конструктором класса XElement. Если необходимо отложенное конструирование XML-элементов, следует воспользоваться классом XStreamingElement.
string[] names = {"John", "Paul", "George", "Pete"};
var xml = new XStreamingElement("Beatles",
from n in names
select new XStreamingElement("name", n));
names[3] = "Ringo";
Console.WriteLine(xml); // Ринго заменил Пита Беста