Сегодня я продолжаю разговор о трех нововведениях, которые мне понравились в VS 2008. Не смотря на то, что я пока не рекомендую использовать Linq к базам (не запрещаю, а просто не могу рекомендовать, пока сам не увидел реальную выгоду), для доступа к XML эту выгоду я уже увидел и однозначно рекомендую к использованию.
Допустим, что у нас есть XML файлик со следующим содержимым
<?xml version="1.0"?> <peoples Version="1"> <Persen name="Smirnov" city="Vologda" phone="01" /> <Persen name="Flenov" city="Moscow" phone="02" /> <Persen name="Ivanov" city="Piter" phone="03" /> <Persen name="Petrov" city="Moscow" phone="04" /> <Persen name="Sodorov" city="Moscow" phone="05" /> <Persen name="Leonov" city="Rostov" phone="06" /> <Persen name="Ketei" city="Piter" phone="07" /> </peoples>
Как нам загрузить из него данные? С помощью Linq эта задача решается легко и не принужденно. Способ 1 - загрузить XML файл и выполнить к нему запрос:
static IEnumerableGetPeoples() { return from c in XDocument.Load("peoples.xml"). Descendants("peoples").Descendants() select new Person { UserName = (string)c.Attribute("name"), City = (string)c.Attribute("city"), Phone = (string)c.Attribute("phone") }; }
Во время загрузки создается массив из классов Person. Этот класс я уже описывал в предыдущей статье 3 возможности, которые мне понравились
Метод GetPeoples() написанный выше возвращает все строки. Чтобы выбрать только москву, можно выполнить следующий код:
var results = from c in GetPeoples() where c.City == "Moscow" select c;
Еще один вараинт запроса:
Console.WriteLine("Query result for Piter"); XDocument doc = XDocument.Load("peoples.xml"); var r = from c in doc.Descendants("peoples").Descendants() where (string)c.Attribute("city") == "Piter" select c;
Этот вариант проще, потому что не нужно использовать вспомогательный класс Person. Обработка идет сразу же над данными XML файла.
А теперь допустим, что нам нужно выбрать всех, кто живет в Питере и сохранить их в отдельный файл. С помощью Linq эта задача решается очень даже красиво:
XElement outXML = new XElement("PeoplesFromPiter", from person in r select new XElement("Person", new XAttribute("name", (string)person.Attribute("name")), new XElement("city", (string)person.Attribute("city")), new XElement("phone", (string)person.Attribute("phone")) )); outXML.Save("out.xml");
Прекрасно? Я думаю да. Полный код, объединяющий все эти примеры:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; namespace XMLLinq { public class Person { public string UserName { get; set; } public string City { get; set; } public string Phone { get; set; } public override string ToString() { return UserName + "\t" + City + "\t" + Phone; } } class Program { // загрузка в массив XML данных static IEnumerableGetPeoples() { return from c in XDocument.Load("peoples.xml"). Descendants("peoples").Descendants() select new Person { UserName = (string)c.Attribute("name"), City = (string)c.Attribute("city"), Phone = (string)c.Attribute("phone") }; } static void Main(string[] args) { // Выполнение запроса к загруженным // с помощью GetPeoples данным Console.WriteLine("Query result Moscow"); var results = from c in GetPeoples() where c.City == "Moscow" select c; foreach (var c in results) Console.WriteLine(c); // обращение непосредственно к данным // без промежуточного массива Console.WriteLine("Query result for Piter"); XDocument doc = XDocument.Load("peoples.xml"); var r = from c in doc.Descendants("peoples").Descendants() where (string)c.Attribute("city") == "Piter" select c; foreach (var c in r) Console.WriteLine(c); // Выбираем всех питерцев и сохраняем в отдельный файл XElement outXML = new XElement("PeoplesFromPiter", from person in r select new XElement("Person", new XAttribute("name", (string)person.Attribute("name")), new XElement("city", (string)person.Attribute("city")), new XElement("phone", (string)person.Attribute("phone")) )); outXML.Save("out.xml"); Console.ReadLine(); } } }
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым
Спасибо за статью
Михаил, ответьте пожалуйста на такой вопрос:
Далее на блоге в основном будут статьи о майкрософт и её продукции?
просто и красиво: 2 вещи, которые я не нашел в С++ и за которые мне нравится с#
2GN: Блог будет о том, что меня больше интересует в данный момент. На данный момент я больше программирую на C#, но не факт, что завтра буду писать здесь о Visual Basic или Java. Хотя нет, завтра об этом точно писать не буду, потому что C# похоже влез в мою голову на долго.
1. Да, технологии клиент-сервер просто "нечего делать" после появления связки XML-Linq. Полный фетч на клиента, а затем только уменьшение выборки (задание условая) полный бред, при выборке даже средних размеров;
2. Согласно DOM (Documentum Object Model) по умолчанию ВЕСЬ XML файл грузится целиком в оперативную память, а только затем данные доступны для обработки через методы класса XDocument. Были у нас "умельцы" которые присылали нам справочник банков в формате XML
~ 900MB, так пока не заставили присылать справочник частями, серваку было "плохо" при загрузке справочника со всеми вытекающими последствиями.
З.Ы. Данная технология может использоваться только для маленьких наборов данных, например хранении и считывании настроек приложения.
> Данная технология может использоваться только для маленьких наборов данных
А кто-то использует XML как базу данных?
Спасибо я тоже начал VS мучать
> А кто-то использует XML как базу данных?
Мы используем MS SQL. В таблицу вписываем XML файл с данными
насколько я помню linq поддерживает в данный момент только ms sql...
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.