Linq к простому запросу XML

Я не получаю эту вещь Linq. Я могу записать сложные SQL-запросы и записал несколько xpaths. Я пытаюсь изучить Linq XML и не могу закончить свою первую попытку несмотря на детально изучение каждого краткого примера, я могу Google.

Данный XML:

<Manufacturer ManufacturerName="Acme">
 <Model ModelName="RobotOne">
  <CommandText CommandName="MoveForward">MVFW</CommandText>
  <CommandText CommandName="MoveBack">MVBK</CommandText>

Входом запроса является "Высшая точка", "RobotOne", "MoveBack", я хочу вывод "MVBK"

Не уверенный, если бы это - лучший способ создать XML, как я сделал бы это с элементами вместо атрибутов? Существует несколько производителей и моделей и много кодов

6
задан Ahmad Mageed 5 February 2010 в 06:21
поделиться

4 ответа

Предполагая, что вы используете эту инициализацию:

string xml = @"
<Manufacturer ManufacturerName='Acme'>
 <Model ModelName='RobotOne'>
  <CommandText CommandName='MoveForward'>MVFW</CommandText>
  <CommandText CommandName='MoveBack'>MVBK</CommandText>
</Model>
</Manufacturer>";

XElement topElement = XElement.Parse(xml);

Вы можете получить результат с помощью следующего запроса LINQ:

string commandText = topElement.Elements("Model")
    .Where(element => (string)element.Attribute("ModelName") == "RobotOne")
    .Elements("CommandText")
    .Where(element => (string)element.Attribute("CommandName") == "MoveBack")
    .Select(element => element.Value)
    .FirstOrDefault();

Если этот XML вложен ниже, вам понадобится больше комбинаций Select / Where.

4
ответ дан 9 December 2019 в 20:43
поделиться

Я расширил ваш XML и продемонстрировал, как получить текст команды MoveBack. Я также добавил пример, чтобы взять модели роботов для конкретного производителя и перечислить команды каждого робота. Первый пример разбит на части, чтобы продемонстрировать, как ходить по структуре XML, чтобы получить элемент за раз. Второй пример выполнен в одном запросе. Конечно, это зависит от того, насколько хорошо вы знаете свои данные. Вы должны использовать SingleOrDefault и проверять на ноль перед использованием результата, если вы ожидаете, что он не будет существовать. Также, проверка атрибутов важна, если они не существуют. Этот код предполагает, что XML закончен.

Что касается структуры XML, то она выглядит нормально. Сохранение общих команд CommandText позволяет поддерживать различные команды. Если команды всегда одни и те же, они могут быть своими собственными элементами. Можно сделать так, чтобы модель называла свой собственный элемент, но оставлять его как есть - как атрибут - имеет смысл.

string input = @"<root>
    <Manufacturer ManufacturerName=""Acme"">
        <Model ModelName=""RobotOne"">
            <CommandText CommandName=""MoveForward"">MVFW</CommandText>
            <CommandText CommandName=""MoveBack"">MVBK</CommandText>
        </Model>
        <Model ModelName=""RobotTwo"">
            <CommandText CommandName=""MoveRight"">MVRT</CommandText>
            <CommandText CommandName=""MoveLeft"">MVLT</CommandText>
        </Model>
    </Manufacturer>
    <Manufacturer ManufacturerName=""FooBar Inc."">
        <Model ModelName=""Johnny5"">
            <CommandText CommandName=""FireLaser"">FL</CommandText>
            <CommandText CommandName=""FlipTVChannels"">FTVC</CommandText>
        </Model>
        <Model ModelName=""Optimus"">
            <CommandText CommandName=""FirePlasmaCannon"">FPC</CommandText>
            <CommandText CommandName=""TransformAndRollout"">TAL</CommandText>
        </Model>
    </Manufacturer>
</root>";
var xml = XElement.Parse(input);

// get the Manufacturer elements, then filter on the one named "Acme".
XElement acme = xml.Elements("Manufacturer")
                   .Where(element => element.Attribute("ManufacturerName").Value == "Acme")
                   .Single(); // assuming there's only one Acme occurrence.

// get Model elements, filter on RobotOne name, get CommandText elements, filter on MoveBack, select single element
var command = acme.Elements("Model")
                  .Where(element => element.Attribute("ModelName").Value == "RobotOne")
                  .Elements("CommandText")
                  .Where(c => c.Attribute("CommandName").Value == "MoveBack")
                  .Single();

// command text value
string result = command.Value;
Console.WriteLine("MoveBack command: " + result);

// one unbroken query to list each FooBar Inc. robot and their commands
var query = xml.Elements("Manufacturer")
               .Where(element => element.Attribute("ManufacturerName").Value == "FooBar Inc.")
               .Elements("Model")
               .Select(model => new {
                    Name = model.Attribute("ModelName").Value,
                    Commands = model.Elements("CommandText")
                                    .Select(c => new {
                                        CommandName = c.Attribute("CommandName").Value,
                                        CommandText = c.Value
                                    })
               });

foreach (var robot in query)
{
    Console.WriteLine("{0} commands:", robot.Name);
    foreach (var c in robot.Commands)
    {
        Console.WriteLine("{0}: {1}", c.CommandName, c.CommandText);
    }
    Console.WriteLine();
}

Если Вы решили использовать XDocument вместо него, Вам нужно использовать корень: xml.Root.Elements(...)

1
ответ дан 9 December 2019 в 20:43
поделиться

Если у вас возникли проблемы со всем LINQ to XML, я бы посоветовал сделать небольшой шаг назад и просто взглянуть на linq в общем. Я считаю, что linq очень стоит затраченных усилий и многократно окупит вас, особенно когда мы мигрируем в мир множества ядер.

Я бы посоветовал вам на мгновение забыть об XML и просто подумать о том, что делает linq - после того, как вы поймете, что такое linq, это упростит понимание специализированных вещей для XML.Это помогает мне думать о linq с учетом следующих двух вещей:

  1. Он выражает стандартные «операторы» (методы расширения) для всего, что реализует интерфейс IEnumerable Другими словами, linq - это просто вызов метода. Некоторые методы принимают код (Func), некоторые (First ()) - нет.
  2. это позволяет вам меньше беспокоиться о том, как эти операторы дают вам результат, и больше о просто объявляет о ваших намерениях .

Нам, специалистам по императивному языку, трудно отказаться от минутной (сверх) спецификации того, как получить результат. По сути, linq дает нам способ объявить , что нам нужен результат, не говоря точно, как его получить. Вот почему, IMO, так важно изучить linq, поскольку именно это точное «отделение» намерения от точного «как» - это действительно крутая часть linq. По сути, он привносит концепции функционального языка в убогий старый императивный C #.

Полезным подспорьем для изучения LINQ является написание императивного кода C #, который делал бы то же самое . Сделайте это несколько раз, и внезапно вы увидите шаблон , который linq делает за вас. Так, например, рассмотрим объявление linq-to-object.

string[] names= new string[] { "kevin", "tristan", jen" };
var result = names.where(n => n.length() > 3);

аналогом запроса linq в C # будет:

List<string> list = new List<string>();
foreach(string n in names)
{
    if (n.length > 3) list.add(n);
}

Я думаю, в этом примере довольно легко увидеть, как linq делает то же самое, что и foreach (в действительности это очень близко к этому) - но у вас нет всей этой ерунды, которая представляет собой просто компиляторную липучку. В версии для linq меньше слизи и больше намерений.Другой способ выразиться в том, что linq неявно выполняет за вас скучный шаблонный материал , позволяя вашему коду просто показать интересную часть.

С функциональной точки зрения метод where () является функцией более высокого порядка . Это просто означает, что это функция, которая сама принимает или возвращает функцию. Где () принимает лямбду - интересная часть цикла . Лямбда - это анонимная функция в C #, поэтому Where () принимает функцию, поэтому она высшего порядка . Я упоминаю об этом, потому что эта концепция является очень мощной и ключевой для понимания linq и дает представление о том, как linq на самом деле представляет собой совершенно новую программную модель (функциональное программирование), прикрепленную к C #. Получение этого «высшего порядка» очень полезно для понимания работы linq.

Я думаю, что работа с прямыми запросами List , подобными приведенному выше, - лучший способ понять, как работает linq. После того, как вы почувствуете себя комфортно с беспорядочными запросами L-2-O, посмотрите еще раз на материал XML - я думаю, вы обнаружите, что тогда они будут иметь больше смысла.

С выходом Reactive framework в .NET 4.0, мы увидим, что linq расширяется не только для запросов «pull», но и для сценариев «push». То есть: коллекция будет запускать код при изменении. Я считаю, что концепции функционального программирования (из которых linq - это туннель C #) - наиболее вероятные способы решения проблем параллелизма и параллелизма, поэтому очень важно их изучить, а не только для того, чтобы код более лаконичный.

5
ответ дан 9 December 2019 в 20:43
поделиться

Для бизнес-данных, если данные являются личными, я бы использовал защищенное соединение, в противном случае достаточно аутентификации форм.

Если вы решите использовать защищенное соединение, обратите внимание, что у меня нет опыта обеспечения безопасности веб-сайтов, я просто отказываюсь от того, с чем столкнулся во время собственного личного опыта. Если я ошибаюсь в любом случае, пожалуйста, не стесняйтесь исправлять меня.

Что делать, чтобы подготовить свой веб-сайт для https. (Нужно ли изменять код/конфигурацию)

Чтобы включить SSL (Secure Sockets Layer) для вашего веб-сайта, необходимо настроить сертификат, код или конфигурацию, которые не изменяются.

Я включил SSL для внутреннего веб-сервера, используя OpenSSL и ActivePerl из этого онлайн-руководства . Если это используется для большей аудитории (моя аудитория была менее 10 человек) и находится в открытом доступе, я предлагаю искать профессиональные альтернативы.

Это SSL и https один и тот же...

Не совсем, но они идут рука об руку! SSL обеспечивает шифрование и расшифровку данных при просмотре веб-сайта, https - это URI, необходимый для доступа к защищенному веб-сайту. При попытке доступа к http://secure.mydomain.com появится сообщение об ошибке.

Нужно ли подавать заявку с кем-то, чтобы получить какую-либо лицензию или что-то еще.

Вам нужно получить не лицензию, а сертификат. Можно найти компании, которые предлагают профессиональные услуги с защищенными веб-сайтами, например, VeriSign .

Нужно ли защищать все мои страницы или только страницу входа в систему...

После включения сертификата для mydomain.com каждая страница под * .mydomain.com будет защищена.

-121--787537-

Если вы пытаетесь преобразовать биты int в представление double , вам нужно привести адрес не значение. Вы также должны убедиться, что размеры совпадают:

uint64_t x = 0x4045000000000000;
double y = *reinterpret_cast<double *>(&x);
-121--961175-

Не совсем ответ, но XPath не сделает код немного проще?

  var result1 = XDocument
            .Load("test.xml")
            .XPathSelectElements("/Manufacturer[@ManufacturerName='Acme']/Model[@ModelName='RobotOne']/CommandText[@CommandName='MoveBack']")
            .FirstOrDefault().Value;
2
ответ дан 9 December 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: