#c# #xml #linq
#c# #xml #linq
Вопрос:
Я пытаюсь заставить запрос LINQ работать, находя информацию для входа в систему из XML-файла, где у родительского элемента есть атрибут типа, и мне нужны значения элементов под ними. Итак, без тегов XML у меня есть:
Users
Username type=Test
Login testuser1
Password password
Username type=Test2
Login testuser2
Password password
Поскольку мне нужно будет извлекать многие из этих значений, мне нужна функция, в которой я могу присвоить ей тег типа и вернуть правильное значение имени входа, я пробовал это несколькими разными способами и не заставил LINQ делать то, что я хочу. Вероятно, я что-то упускаю, но я пытаюсь использовать примеры Microsoft и некоторые другие, но я не нашел ничего похожего на то, что я пытаюсь сделать, чтобы пройти. Я лучше всего учусь на примере и тестировании, и до сих пор у меня ничего не получилось, чтобы работать правильно.
Я пробовал две разные версии этого:
public string getTestUserInfo(string type)
{
Assert.IsNotNullOrEmpty(type);
XElement root = XElement.Load("TestInformation.xml");
IEnumerable<XElement> myusername =
from el in root.Elements("Username")
where (string)el.Attribute("Type") == type
select el.Element("Login");
string username = myusername.ToString();
return username;
}
Я надеялся, что он вернет имя пользователя типа Test или Test2 в зависимости от того, что я отправил, а затем вернет мне el.Значение Login . Кажется, я не могу правильно использовать синтаксис для получения значения. Я также пытался:
Assert.IsNotNullOrEmpty(type);
XElement root = XElement.Load("TestInformation.xml");
string username = (string)
(from el in root.Elements("Username")
where (string)el.Attribute("Type") == type
select el.Element("Login"));
return username;
Но строка username = (string) выдает мне ошибки о невозможности преобразовать XElement в string . Если я просто хочу получить первый логин, я могу сделать это с помощью root.Потомки, но я хотел бы иметь возможность вызывать любое имя входа, которое я хочу, только по типу.
Это выполнимо?
Ответ №1:
В обоих случаях вы пытаетесь преобразовать IEnumerable в строку. Попробуйте использовать .Сначала, чтобы получить первый элемент Login вместо:
string username = root.Elements("Username")
.First(el => (string)el.Attribute("type") == type)
.Element("Login")
.Value;
Еще одна вещь, на которую нужно обратить внимание. В ваших примерах вы используете верхний регистр атрибута T on(«Тип»), но в XML он указан в нижнем регистре. XML, как и C #, чувствителен к регистру.
Комментарии:
1. Очень круто, я не знал, что вы можете написать это так. Я попробовал этот пример и в строке для root. Элементы («Имя пользователя») Я получаю: последовательность не содержит соответствующего элемента. Я недостаточно знаком с сообщениями об ошибках, чтобы понять, что не так.
2. Эта ошибка указывает на то, что один из шагов не вернул никаких результатов, и, следовательно, следующий метод не может быть оценен должным образом. Попробуйте протестировать это, проверяя каждый метод, чтобы убедиться, что они возвращают ожидаемые результаты. Кроме того, убедитесь, что нет пространства имен XML, которое вы забыли упомянуть, поскольку 95% ошибок LINQ to XML без возвращаемых результатов вызваны отсутствующим объявлением пространства имен в запросе. В-третьих, убедитесь
UserName
, что иLogin
действительно прописные буквы в вашем источнике XML.3. Я не понимал, что наличие еще одного уровня в XML будет иметь значение, впервые я действительно что-то сделал с LINQ, но в итоге я переключил root. Элементы в root. Потомки и это решило проблему. Большое спасибо, я не думаю, что зашел бы так далеко без помощи … и мне еще далеко идти в изучении этого материала!
4. Да, в этом разница между элементом и потомком. Элемент относится к одному уровню вниз по дереву, тогда как потомок относится к любому узлу ниже текущего узла. Если вам нужна дополнительная помощь в изучении LINQ, я могу порекомендовать хорошую книгу
![]()
5. Пожалуйста, сделайте, никогда не помешает увеличить список чтения. Спасибо!