Похоже, вы приложили к этому достойные усилия, поэтому снимаю шляпу перед вами. Я распознаю некоторые ошибки или недоразумения LINQ для начинающих в вашем коде и надеюсь устранить их ниже.
- Если вы ожидаете существование одного элемента, не используйте
Descendants
. Вместо этого используйте Element
. Все значения от «Pool Num» до «WA CAP» - это отдельный элемент XML, который можно получить непосредственно следующим образом: parent.Element(p + "PoolNumber")
, где parent
- родительский элемент нужного элемента.
- Чтобы получить значение элемента, используйте свойство
Value
: parent.Element(p + "PoolNumber").Value
. Использование (string)
приведение не является неправильным, однако предпочтительно использовать его, когда вы подозреваете, что элемент может или не может существовать. Если его не существует, вызов Value
вернет NullReferenceException
, поскольку он будет нулевым. Кастинг это обходит. Простой способ проверить это в моем коде ниже - добавить pool.Element(p + "PoolNumber").Remove();
после объявления pool
и посмотреть, как он сломается. Затем используйте свой подход (string)
и наблюдайте, как он счастливо продолжается.
- Относительно пункта # 1, подход
Element
эффективно заменяет необходимость foreach
на результат, чтобы получить только одно значение. Я рекомендую поиграть с First
, Single
, FirstOrDefault
и SingleOrDefault
методами. У вас есть LINQPad, так что ознакомьтесь с примерами и поиграйте с ними.
Кроме того, имена локальных переменных должны начинаться со строчной буквы в соответствии со стандартными ожиданиями форматирования. Также полезно расположить вызовы методов LINQ на отдельных строках и выровнять их в начале точечной нотации.
Как мне получить запрашиваемые элементы в
появляются горизонтальные и с некоторыми
Разделитель
Используйте метод String.Join
. В .NET 4.0 нет необходимости вызывать ToArray
, так как метод принимает перегрузку для IEnumerable<string>
.
В настоящее время мой код работает только для 1 XML
файл. Как это можно изменить в цикле
для нескольких файлов?
Поместите значения вашего пула в список, затем передайте его поверх него и поместите логику в тело цикла. Смотрите мой код ниже.
Вот очищенная версия вашего кода. Я не был уверен, хотите ли вы, чтобы все заголовки были горизонтальными или были заинтересованы только в использовании разделителя для элементов с несколькими значениями.
// load from websites based on pool numbers in list
var list = new List<string> { "510299", "510300"};
foreach (var poolNumber in list)
{
XElement tags=XElement.Load("http://fapt.efanniemae.com/epooltalk-hvd/pool.xml?type=XML&pn=" + poolNumber + ".XML");
XNamespace p = tags.GetDefaultNamespace();
// export process
XElement pool = tags.Element(p + "Pool");
Console.WriteLine("Pool Num |" + pool.Element(p + "PoolNumber").Value);
Console.WriteLine("CUSIP |" + pool.Element(p + "CUSIP").Value);
Console.WriteLine("PoolPrefix |" + pool.Element(p + "PoolPrefix").Value);
Console.WriteLine("Orig. Bal |" + pool.Element(p + "OriginalSecurityBalance").Value);
Console.WriteLine("Orig. Term |" + pool.Element(p + "WeightedAverageOrigLoanTerm").Value);
Console.WriteLine("Remain Term |" + pool.Element(p + "WAMnthsRemainingToAmortization").Value);
Console.WriteLine("WALA |" + pool.Element(p + "WeightedAverageLoanAge").Value);
Console.WriteLine("Net Rate |" + pool.Element(p + "CurrentAccrualRate").Value);
Console.WriteLine("WA Margin |" + pool.Element(p + "WeightedAverageLoanMarginRate").Value);
Console.WriteLine("SubType |" + pool.Element(p + "SubType").Value);
Console.WriteLine("Updated CAP |" + pool.Element(p + "UpdatedCap").Value);
Console.WriteLine("Issue Date |" + pool.Element(p + "IssueDate").Value);
Console.WriteLine("Maturity Date |" + pool.Element(p + "MaturityDate").Value);
Console.WriteLine("Rate Adj Freq |" + pool.Element(p + "RateAdjustmentFrequency").Value);
Console.WriteLine("Period Cap |" + pool.Element(p + "PerAdjustmentCap").Value);
Console.WriteLine("Pymt Chg Freq |" + pool.Element(p + "PaymentChangeFrequency").Value);
Console.WriteLine("WA MTR |" + pool.Element(p + "WeightedAverageMonthsToRoll").Value);
Console.WriteLine("WA CAP |" + pool.Element(p + "WeightedAverageCap").Value);
var poolFactors = pool.Element(p + "PoolFactors");
var months = poolFactors.Descendants(p + "Month")
.Select(m => m.Value);
Console.WriteLine("Months |" + String.Join(", ", months.ToArray()));
var wacs = poolFactors.Descendants(p + "WAC")
.Select(wac => wac.Value);
Console.WriteLine("WAC |" + String.Join(", ", wacs.ToArray()));
var wams = poolFactors.Descendants(p + "WAM")
.Select(wam => wam.Value);
Console.WriteLine("WAM |" + String.Join(", ", wams.ToArray()));
var factors = poolFactors.Descendants(p + "Factor")
.Select(f => f.Value);
Console.WriteLine("Factor |" + String.Join(", ", factors.ToArray()));
Console.WriteLine();
}