Пересмотрено с учетом новых требований.
- Разделенные детали преобразования каждого конкретного типа и сама логика генерации XML
- Можно легко внедрить поддержку новых типов данных, добавив новую фабрику к провайдеру. Набор поддерживаемых типов в настоящее время ограничен элементами перечисления TypeCode , но, очевидно, это можно легко переключить на другой селектор / идентификатор типа.
- Я должен согласиться с jbtule, что Tuple .Create () действительно выглядит намного лучше, чем конструкция KeyValuePair <,> , никогда раньше не использовал его, приятная штука, спасибо!
Сам метод:
public string ConvertToXml(
IDictionary<string, object> rawData,
Dictionary<TypeCode, Func<object, Tuple<string, string>>> transformationFactoryProvider)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<?xml version='1.0' encoding='utf-8'?><sc/>");
if (rawData != null)
{
Func<object, Tuple<string, string>> defaultFactory =
(raw) => Tuple.Create("string", raw.ToString());
foreach (KeyValuePair<string, object> item in rawData)
{
TypeCode parameterTypeCode = Type.GetTypeCode(item.Value.GetType());
var transformationFactory = transformationFactoryProvider.ContainsKey(parameterTypeCode)
? transformationFactoryProvider[parameterTypeCode]
: defaultFactory;
var transformedItem = transformationFactory(item.Value);
XmlElement xmlElement = doc.CreateElement("pr");
xmlElement.SetAttribute("tp", transformedItem.Item1);
xmlElement.SetAttribute("nm", item.Key);
xmlElement.SetAttribute("vl", transformedItem.Item2);
doc.FirstChild.NextSibling.AppendChild(xmlElement);
}
}
return doc.OuterXml;
}
Пример использования:
// Transformation Factories
// Input: raw object
// Output: Item1: type name, Item2: value in the finally formatted string
Func<object, Tuple<string, string>> numericFactory = raw => Tuple.Create("int", raw.ToString());
Func<object, Tuple<string, string>> dateTimeFactory =
raw => Tuple.Create("datetime", (raw as DateTime?).GetValueOrDefault().ToString("o"));
// Transformation Factory Provider
// Input: TypeCode
// Output: transformation factory for the given type
var transformationFactoryProvider =
new Dictionary<TypeCode, Func<object, Tuple<string, string>>>
{
{TypeCode.Int16, numericFactory},
{TypeCode.Int32, numericFactory},
{TypeCode.Int64, numericFactory},
{TypeCode.DateTime, dateTimeFactory}
};
// Convert to XML given parameters
IDictionary<string, object> parameters = new Dictionary<string, object>
{
{ "SOMEDATA", 12 },
{ "INTXX", 23 },
{ "DTTM", DateTime.Now },
{ "PLAINTEXT", "Plain Text" },
{ "RAWOBJECT", new object() },
};
string xmlParameters = this.ConvertToXml(parameters, transformationFactoryProvider);