Спасибо за все ответы.Жаль, что библиотека .NET XmlSerialization
этого не допускает (думаю, что так и должно быть!).Я ищу как можно более универсальное решение.
Лучшее, которое я мог бы придумать (лучшее, учитывающее критерии максимальной универсальности и в то же время достаточно быстрое для реализации), - позволить сериализовать XmlSerializer
мой класс так, как ему нравится, затем просто преобразуйте выходные данные, переместив определенные элементы во вложенные местоположения.
Что-то в этом роде:
/// <remarks>
/// (angle brackets replaced with round ones to avoid confusing the XML-based documentation comments format)
///
/// Let input XML be:
///
/// (root)
/// (days)3(/days)
/// (/root)
///
/// Calling Reposition on this input with mappings argument being:
/// (key) "days"
/// (value) { "time", "days" }
///
/// Returns:
/// (root)
/// (time days="3" /)
/// (/root)
/// </remarks>
static XElement Reposition(XElement input, KeyValuePair<string, string[]>[] mappings)
{
var result = new XElement(input);
foreach (var mapping in mappings)
{
var element = result.Element(mapping.Key);
if (element == null)
{
continue;
}
var value = element.Value;
element.Remove();
var insertAt = result;
foreach (var breadcrumb in mapping.Value)
{
if (breadcrumb == mapping.Value.Last())
{
insertAt.Add(new XAttribute(breadcrumb, value));
}
else
{
insertAt.Add(new XElement(breadcrumb));
insertAt = insertAt.Element(breadcrumb);
}
}
}
return result;
}
Я думаю, я бы совместил его с пользовательским атрибутомчто-то вроде атрибута XPath
, который, как я хотел, существовал бы: посмотрите пример кода в моем вопросе) и оберните эту функцию в мой собственный класс сериализатора.
Есть какие-нибудь комментарии / идеи по этому подходу?
Я могу представить себе потенциальный недостаток производительности (переписывание / повторный анализ XML после каждой сериализации), но не ожидается, что полученные фрагменты XML будут иметь большой размер, поэтому это, вероятно, незначительно.
Вопрос десериализации не беспокоит меня на данный момент (десериализация уже была реализованаи делается довольно "вручную", XPath и некоторыми служебными методами).