Я ОЧЕНЬ новичок в использовании LINQ. У меня есть следующий XML:Возвращаемые значения элементов по атрибуту с использованием C# и Linq
<?xml version="1.0" encoding="utf-8" ?>
<root>
<RetentionValue code="NR" fullName="Normal Retention">Used for normal retention periods commonly expressed as only numbers (i.e. "25" for 25 years).</RetentionValue>
<RetentionValue code="SR" fullName="Short Retention">Used for short retention periods expressed in terms of months (i.e. "6 months").</RetentionValue>
<RetentionValue code="AR" fullName="Annual Review">Review annually and retain what is needed, dispose of what is not needed.</RetentionValue>
<RetentionValue code="PE" fullName="Permanent">Document is to be retained permanently.</RetentionValue>
<RetentionValue code="EX" fullName="Expiration">Disposal date is calculated from expiration of a contract, loan, or other such instrument.</RetentionValue>
<RetentionValue code="LI" fullName="Lifetime">Disposal date is calculated from the end-of-life date for a piece of equipment or other asset (e.g. software application).</RetentionValue>
<RetentionValue code="TE" fullName="Employee Termination">Disposal date is calculated from the date of termination or retirement of an employee.</RetentionValue>
<RetentionValue code="FR" fullName="Final Resolution">Disposal date is calculated from the date of final resolution for an issue.</RetentionValue>
</root>
В моем коде, я создаю объект, который имеет свойство RetentionEvent
, который имеет значение одного из двух буквенных кодов выше. Я хочу найти элемент с соответствующим атрибутом, а затем вернуть fullName
в одно текстовое поле и значение (многословное описание) в другое текстовое поле. До сих пор у меня есть следующий:
// Construct a RecordDisposal object by passing it a valid retention code.
// An exception will be thrown if the code is not valid.
_rd = new RecordDisposal(RetentionCode.Text);
// Load up XML file with description of codes.
XDocument rangeValues = XDocument.Load("DisposalRangeValues.xml");
XElement codeValue = rangeValues.Root.Elements().Single(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent);
CodeName.Text = codeValue.Attribute("fullName").Value.ToString();
CodeDescription.Text = codeValue.Value.ToString();
Запроса является прямым модом из this кода (я думаю), но я получаю несколько ошибок я не понимаю: «Тело запроса должно заканчиваться с предложением select или групповым предложением « (я думал, что это то, что было для ToList()
), и « Тип выражения в предложении select неверен. Ошибка ввода типа в вызове «Выбрать». » К сожалению, я не понимаю Linq достаточно хорошо, чтобы устранить эту проблему, и «Помощь по этой ошибке» не дает ничего полезного.
Что я сделал неправильно? Кроме того, я подозреваю, что функция ToList()
вернет что-то, что плохо отображается в функции ToString()
, но я ожидал, чтобы выяснить другие вещи, прежде чем обманывать это. Если у кого есть предложение, пожалуйста, предложите его.
EDIT: Измененный код для использования Одиночный, основанный на рекомендации ниже. Обнаружено, что rangeValues
загружает все <root>
как единый узел.
EDIT2: Выяснено. Изменен код для использования rangeValues.Root.Elements()
. Обновленный код выше, чтобы отразить.
Мне нравится метод «Single()», и, как вы подозреваете, не хотите, чтобы «SingleOrDefault()» или любой другой предоставили.Тем не менее, я получаю исключение, сказанное «Последовательность не содержит соответствующего элемента», когда я это знаю. Ну, по крайней мере, я знаю, что значение представлено. Независимо от того, загружается ли XML и правильно разбирается, это совсем другое дело. –
Понял. Необходимо использовать 'rangeValues.Root.Elements()'. –