Merci, excellent travail @Matthew et @Martin.
J'ai apporté quelques modifications pour prendre en compte les Nullables et les Enums. J'ai également modifié pour que les éléments du tableau soient nommés en fonction du nom de la propriété + index.
Voici le code si quelqu'un est intéressé
public static class ObjectExtensions {
#region Champs Privés
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
#endregion Champs Privés
#region .ToXml
///
/// Convertit un type anonyme en XElement.
///
/// L'entrée.
/// Renvoie l'objet sous sa représentation XML dans un XElement.
public static XElement ToXml(this object input) {
return input.ToXml(null);
}
///
/// Convertit un type anonyme en XElement.
///
/// L'entrée.
/// Le nom de l'élément.
/// Renvoie l'objet sous sa représentation XML dans un XElement.
public static XElement ToXml(this object input, string element) {
return _ToXml(input, element);
}
private static XElement _ToXml(object input, string element, int? arrayIndex = null, string arrayName = null) {
if (input == null)
return null;
if (String.IsNullOrEmpty(element)) {
string name = input.GetType().Name;
element = name.Contains("AnonymousType")
? "Object"
: arrayIndex != null
? arrayName + "_" + arrayIndex
: name;
}
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null) {
var type = input.GetType();
var props = type.GetProperties();
var elements = props.Select(p => {
var pType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
var name = XmlConvert.EncodeName(p.Name);
var val = pType.IsArray ? "array" : p.GetValue(input, null);
var value = pType.IsArray
? GetArrayElement(p, (Array)p.GetValue(input, null))
: pType.IsSimpleType() || pType.IsEnum
? new XElement(name, val)
: val.ToXml(name);
return value;
})
.Where(v=>v !=null);
ret.Add(elements);
}
return ret;
}
#region aides
///
/// Obtient l'élément du tableau.
///
/// Les informations de la propriété.
/// L'objet d'entrée.
/// Renvoie un XElement avec la collection de tableau comme éléments enfants.
private static XElement GetArrayElement(PropertyInfo info, Array input) {
var name = XmlConvert.EncodeName(info.Name);
XElement rootElement = new XElement(name);
var arrayCount = input == null ? 0 : input.GetLength(0);
for (int i = 0; i < arrayCount; i++) {
var val = input.GetValue(i);
XElement childElement = val.GetType().IsSimpleType() ? new XElement(name + "_" + i, val) : _ToXml(val, null, i, name);
rootElement.Add(childElement);
}
return rootElement;
}
#region .IsSimpleType
public static bool IsSimpleType(this Type type) {
return type.IsPrimitive || WriteTypes.Contains(type);
}
#endregion .IsSimpleType
#endregion aides
#endregion .ToXml
}