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);
    }
}
Другие вопросы по тегам