XElement с использованием Flags Enum
В моем коде у меня есть Flags Enum для дней недели, как показано ниже:
[Flags]
public enum DaysOfWeek // enumeration for days of week
{
Sunday = 0x0000001,
Saturday = 0x0000010,
Friday = 0x0000100,
Thursday = 0x0001000,
Wednesday = 0x0010000,
Tuesday = 0x0100000,
Monday = 0x1000000,
MondayToFriday = Monday | Tuesday | Wednesday | Thursday | Friday,
MondayToSaturday = MondayToFriday | Saturday,
NotSaturday = MondayToFriday | Sunday,
Weekend = Saturday | Sunday,
MondayToSunday = MondayToFriday | Weekend,
HolidaysOnly = ~MondayToSunday,
}
И я использую это как в следующем упрощенном примере для вывода XML:
List<DaysOfWeek> profiles = new List<DaysOfWeek>();
profiles.Add(DaysOfWeek.MondayToFriday);
profiles.Add(DaysOfWeek.MondayToSaturday);
profiles.Add(DaysOfWeek.Monday | DaysOfWeek.Tuesday);
XElement xml = new XElement("Profiles",
from DaysOfWeek pf in profiles
select new XElement("Profile",pf.ToString())
);
Console.WriteLine(xml);
Это дает мне вывод:
<Profiles>
<Profile>MondayToFriday</Profile>
<Profile>MondayToSaturday</Profile>
<Profile>Tuesday, Monday</Profile>
</Profiles>
Но то, что я хочу, это:
<Profiles>
<Profile>
<MondayToFriday />
</Profile
<Profile>
<MondayToSaturday />
</Profile>
<Profile>
<Monday />
<Tuesday />
</Profile>
</Profiles>
Я ценю, что формат моего XElement должен быть расширен, чтобы я получал пустые элементы для дней недели, но если я делаю это, то элемент "Tuesday, Monday" выдает исключение, потому что я не могу использовать запятую (или пробел) как часть имени элемента.
Но
а) Если не используется одна из предопределенных групп дней, мне нужно записать элементы в определенном порядке (понедельник, вторник, среда, четверг, пятница, суббота, воскресенье), который задается схемой (см. c ниже). Я усложнил для себя, потому что я определил их в обратном порядке, с понедельником в качестве старшего бита, но это было потому, что старый формат данных, с которым я имел дело, сначала представляет дни как флаги (1/0) в строке в этот порядок, например, понедельник и вторник: "1100000" (понедельник слева, воскресенье справа);
б) я хотел бы иметь возможность выводить соответствующие элементы без необходимости проверять все по отдельности (хотя, думаю, мне придется, если потребуется); а также
в) Выходной формат XML, который я ищу, продиктован стандартом с XSD, и я не могу его изменить.
Какие-нибудь яркие идеи?
1 ответ
Следующее может удовлетворить ваши потребности.
Он анализирует выходную строку флага и определяет, должен ли контент быть элементом XElement или списком.
public static object GetDaysOfWeekXelementContent(DaysOfWeek pf)
{
var pfStr = pf.ToString();
if (pfStr.Contains(","))
{
return pfStr.Split(',').Select(x => new XElement(x.Trim()));
}
else
{
return new XElement(pfStr);
}
}
static void Main(string[] args)
{
List<DaysOfWeek> profiles = new List<DaysOfWeek>();
profiles.Add(DaysOfWeek.MondayToFriday);
profiles.Add(DaysOfWeek.MondayToSaturday);
profiles.Add(DaysOfWeek.Monday | DaysOfWeek.Tuesday);
XElement xml = new XElement("Profiles",
from DaysOfWeek pf in profiles
select new XElement("Profile", GetDaysOfWeekXelementContent(pf))
);
Console.WriteLine(xml);
}
Изменить Что касается сортировки значений, вы объявляете свои значения с воскресенья по понедельник. Вы можете анализировать значения одно за другим, сортировать их по убыванию, чтобы иметь с понедельника по воскресенье.
Следующее должно сделать:
public static object GetDaysOfWeekXelementContent(DaysOfWeek pf)
{
var pfStr = pf.ToString();
if (pfStr.Contains(","))
{
return pfStr.Split(',').Reverse().Select(x => new XElement(x.Trim()));
}
else
{
return new XElement(pfStr);
}
}