Сегодня я продолжаю разговор о трех нововведениях, которые мне понравились в 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 IEnumerable GetPeoples()
{
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...
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.