LINQ, Трансформації XML

За допомогою LINQ to XML можна виконувати трансформації XML, використовуючи для цього два абсолютно різні підходи. Перший підхід полягає у застосуванні мови через класи-мости -XmlReader таXmlWriter. Другий підхід передбачає використання для трансформацій самого API-інтерфейсу LINQ to XML за рахунок функціонального конструювання цільового документа XML та вбудовування запиту LINQ to XML на певний документ XML.

Застосування XSLT має ту перевагу, що це стандартна технологія XML. Існує інструментарій, який допомагає в написанні, налагодженні та тестуванні трансформацій XSLT. До того ж, оскільки вона вже існує, доступні готові XSLT-документи, які можна використовувати в новому коді із застосуванням LINQ to XML.

Існує безліч доступних XSLT-документів, із яких можна вибрати потрібні. До того ж, використання XSLT для трансформацій є найбільш динамічним. На відміну від застосування підходу на основі функціонального конструювання LINQ to XML, повторно компілювати код зміни трансформації не знадобиться. Проста зміна документа XSLT дозволяє модифікувати трансформацію під час виконання.

І, нарешті, XSLT — широко відома технологія, і є чимало знаючих її розробників, які можуть допомогти. Що стосується підходу на основі функціонального конструювання, то поки що, на початковому етапі існування LINQ, це ще не так.

Застосування підходу з функціональним конструюванням не вимагатиме великих витрат. Воно дозволить виконувати трансформації XML, не знаючи нічого, крім LINQ to XML. Тому якщо ви не знайомі з XSLT, а потреби в трансформації скромні, цей підхід може виявитися більш відповідним. До того ж, хоча функціональне конструювання менш зручне, ніжпроста модифікація документа XSLT, необхідність перекомпіляції коду модифікації трансформацій може додати безпеки.

Трансформації з використанням XSLT

Щоб здійснити трансформацію з використанням XSLT, необхідно звернутися до класів-мостів XmlWriter та XmlReader, екземпляри яких виходять із методів CreateWriter та CreateReader класів XDocument.

Приклад, наведений нижче, вимагає деяких пояснень, які будуть наводитися в міру просування коду. Для початку визначається таблиця стилів трансформації:

Тут немає нічого особливо визначного. Просто вказується XSL-розмітка для створення деякої HTML-розмітки, призначеної для відображення типового XML-документа із співробітниками у вигляді HTML-таблиці. Далі створюється XML-документ із співробітниками:

Це просто простий XML-документ. А тепер про те, де починається магія. Потрібно створити новий XDocument для трансформованої версії. Потім з цього документа буде побудовано XmlWriter, створено екземпляр об'єктаXslCompiledTransform, завантажено об'єкт трансформації за допомогою таблиці стилів трансформації та виконано трансформацію вхідного XML-документа у вихідний XmlWriter:

Зрозуміло, що після цього трансформована версія документа відображається. Як бачите, для виконання трансформації використовуються обидва класи-мости — XmlWriter і XmlReader. Нижче показано результат:

трансформації

Трансформація з використанням функціонального конструювання

Хоча LINQ to XML підтримує трансформацію XSLT, є дуже ефективні способи виконання трансформацій на основі самого API-інтерфейсу LINQ to XML.

Логічно міркуючи, трансформація може бути зведена до комбінації функціонально сконструйованого дерева XML із вбудованим запитом XML.Для трансформації комбінуйте функціональне конструювання з вбудованим запитом XML LINQ.

XML-трансформації найкраще пояснити з прикладу. У багатьох прикладах, наведених раніше, присвячених LINQ to XML, робота здійснювалася з наступним деревом XML:

Припустимо, що це дерево XML необхідно трансформувати в наступне:

Для проведення цієї трансформації використовуватиметься функціональне конструювання із вбудованим запитом. За допомогою цього підходу буде функціонально сконструйовано новий документ, який відповідає бажаній вихідній деревоподібній структурі XML, з отриманням необхідних для цього даних із вихідного документа XML за допомогою запиту LINQ to XML. Функціональне конструювання та логіка запиту визначаються бажаною вихідною деревоподібною структурою. Код представлений нижче:

У наведеному коді спочатку створюється XML-документ xDocument, який трансформуватиметься і відображатиметься. Потім будується новий трансформований документ xTransDocument та кореневий вузол MediaEmployees, включаючи атрибут type. Потім генерується елемент Employee кожного елемента Employee вихідного XML з допомогою операцій Element і Elements. Після цього будується проекція елемента Employee, використовуючи LINQ-операцію Select І, нарешті, трансформований XML-документ відображається. Давайте подивимося, чи отримано в результаті те, що потрібно:

трансформації

Все пройшло блискуче! Висновок відповідає очікуванням. Непогано, якщо врахувати, що нічого не використовувалося крім LINQ to XML.