C# Добавление нескольких элементов в список с помощью xdocument
<?xml version="1.0" encoding="utf-8" ?>
<root>
<fileUploadSpecification>
<DirectoryPath>C:\watchFolder</DirectoryPath>
<Region>us-west-2</Region>
<UploadBucket>configurationtestbucket</UploadBucket>
<FileType>
<type>*.txt</type>
<type>*.OpticomCfg</type>
</FileType>
</fileUploadSpecification>
<fileUploadSpecification>
<DirectoryPath>C:\watchFolder</DirectoryPath>
<Region>us-west-2</Region>
<UploadBucket>loguploadbucket</UploadBucket>
<FileType>
<type>*.Xml</type>
<type>*.Json</type>
</FileType>
</fileUploadSpecification>
</root>
Это XML-файл, который мне нужно проанализировать, я хочу получить каждый экземпляр fileUploadSpecification, чтобы я мог поместить каждый набор деталей в список, я думаю, что был бы уместен какой-то тип цикла for, где я делаю цикл и добавляю первый установить детали загрузки, а затем перебрать и добавить второй. Это то, что у меня сейчас есть, но оно никогда не попадает во второй элемент fileUploadSpecification, оно просто возвращает тот же самый снова. Идея состоит в том, чтобы создать новую SettingsData для каждого набора элементов fileUploadSpecification, будь то два, как показано выше, или 10.
public interface ISettingsEngine
{
IEnumerable<SettingsData> GetSettings();
}
public class SettingsEngine : ISettingsEngine
{
public IEnumerable<SettingsData> GetSettings()
{
List<SettingsData> dataList = new List<SettingsData>();
try
{
var xDoc = XDocument.Load("File1.xml");
var instancesToParse = xDoc.Root.Elements().Count();
var fileCount = xDoc.Root.Elements("FileType").Count();
for (int x = 0; x < instancesToParse; x++)
{
var newSettingsData = new SettingsData();
newSettingsData.UploadBucket = xDoc.Root.Element("fileUploadSpecification").Element("UploadBucket").Value;
newSettingsData.Region = xDoc.Root.Element("fileUploadSpecification").Element("Region").Value;
newSettingsData.DirectoryPath = xDoc.Root.Element("fileUploadSpecification").Element("DirectoryPath").Value;
var query = xDoc.Root.Descendants("FileType").Elements("type");
foreach (XElement e in query)
{
newSettingsData.FileType.Add(e.Value);
}
dataList.Add(newSettingsData);
}
return dataList;
}
catch(Exception)
{
return dataList;
}
}
}
public class SettingsData
{
public List<string> FileType { get; set; }
public string DirectoryPath { get; set; }
public string Region { get; set; }
public string UploadBucket { get; set; }
public SettingsData()
{
FileType = new List<string>();
}
}
2 ответа
var dataList = (from fus in xDoc.Root.Elements("fileUploadSpecification")
select new SettingsData
{
UploadBucket = fus.Element("UploadBucket").Value,
Region = fus.Element("Region").Value,
DirectoryPath = fus.Element("DirectoryPath").Value,
FileType = fus.Element("FileType")
.Elements("type").Select(f =>f.Value).ToList()
}).ToList();
Каждый раз, просматривая цикл, вы смотрите вверх fileUploadSpecification
элемент снова и снова. Вы использовали Elements()
Метод уже в нескольких местах. Это тот, который вы хотите. Всегда благосклонность foreach
над for
в C#, когда вы перебираете коллекцию. Это быстрее (для кодирования, а не во время выполнения) и менее подвержено ошибкам.
foreach (var uploadSpec in xDoc.Root.Elements("fileUploadSpecification"))
{
var newSettingsData = new SettingsData();
newSettingsData.UploadBucket = uploadSpec.Element("UploadBucket").Value;
newSettingsData.Region = uploadSpec.Element("Region").Value;
newSettingsData.DirectoryPath = uploadSpec.Element("DirectoryPath").Value;
var types = uploadSpec.Descendants("FileType").Elements("type").Select(e => e.Value);
foreach (var type in types)
{
newSettingsData.FileType.Add(type);
}
// Or if newSettingsData.FileType is List<String>...
//newSettingsData.FileType.AddRange(types);
dataList.Add(newSettingsData);
}
Функционально ответ Джеймса Керрана такой же, но в лучшем виде.