Linq2Xml ограничение на загрузку из XML файла

418
23 декабря 2016, 11:41

Здравствуйте есть большой XML файл, более 500000 записей, из него часто приходится дергать корректировочную информацию. чтобы не грузить файл полностью а с помощью linq выполнить фильтрацию записей.

<root>
 <esrs>
   <rc int_ESR="-1594" str_Name="ПОБОЖИЙ"/>
   <rc int_ESR="-1593" str_Name="ФЕДОСЕЕВ"/>
   <rc int_ESR="-1592" str_Name="ГЛУХАРИНЫЙ"/>
 </esrs>

код загрузки всех станций:

  public IEnumerable<Station> SetResponse(XDocument xmlDoc, IEnumerable<Station> stationValid)
    {
            var listStationsNameQuery =
            from train in xmlDoc.Descendants("rc")
            select new
            {
                Esr = (string)train.Attribute("int_ESR"),
                Name = (string)train.Attribute("str_Name"),
            };
    }   

А мне нужно грузить только станции указанные в stationValid по равенству ESR кода? Подскажите как сделать такое ограничение на Linq запрос?

Answer 1

С XDocument не выйдет не грузить весь документ в память. Если вам нужно только читать информацию, нужно использовать XmlReader, он потоковый.

Например, чтобы найти все str_Name, соответствующие данному int_ESR, подойдёт вот такой код:

var goodEsrValues = new HashSet<string>(
    stationValid.Select(station => station.ESR.ToString()));
using (TextReader tr = ...)
using (var reader = XmlReader.Create(tr))
{
    while (reader.Read())
    {
        if (reader.NodeType != XmlNodeType.Element || reader.Name != "rc")
            continue;
        var attr = reader.GetAttribute("int_ESR");
        if (!goodEsrValues.Contains(attr))
            continue;
        var name = reader.GetAttribute("str_Name");
        if (name != null)
            yield return name;
    }
}
Answer 2

Если бы надо было найти по одному ключу, можно было бы XPath использовать, в вашем случае может подойдёт такой вариант:

public IEnumerable<Station> SetResponse(XDocument xmlDoc, IEnumerable<Station> stationValid)
{
        var validEsr = new HashSet<string>(stationValid.Select(s => s.Esr));
        foreach(var elem in xmlDoc.Descendants("rc"))
        {
            var esr = (string)train.Attribute("int_ESR");
            if (validEsr.Contain(esr))
            {
                yield return new
                {
                    Esr = esr,
                    Name = (string)train.Attribute("str_Name"),
                };
            }
        }
}
READ ALSO
cefsharp не запоминает логин

cefsharp не запоминает логин

Подскажите, как в CefSharp сделать так, что бы при повторном входе появлялось окно с логином (пароль при этом не запоминать)

441
Направление зависимостей в приложении

Направление зависимостей в приложении

Вопрос состоит в том какие модули от чего зависят? Хочу разобрать на примере веб приложения (серверная часть)Используемая технология asp

360
Как увеличить размер картинки ImageList больше 256x256?

Как увеличить размер картинки ImageList больше 256x256?

Как увеличить размер картинки imagelist ImageList больше 256;256 256x256?

390
Несколько значений разных типов в одном ключе

Несколько значений разных типов в одном ключе

Я не знаю, как правильно сформулировать вопрос, напишу как есть

348