I want to write a generic method that returns a XML once a collection of type T is passed. I tried below code, but doesn't work as expected. Any advise on enhancing this to include element attributes is highly appreciated. Thanks
public XElement GetXElements<T>(IEnumerable<T> colelction,string parentNodeName) where T : class
{
XElement xml = new XElement(typeof(T).GetType().Name);
foreach(var x in typeof(T).GetProperties())
{
var name = x.Name;
var value = typeof(T).GetProperty(x.Name).GetValue(x);
xml.Add(new XElement(name,value));
}
return xml;
}
For example, if I send a collection like below to above method,
var col = new List<Employee>()
{
new Employee
{
FirstName = "John",
Sex= "Male"
},
new Employee
{
FirstName = "Lisa",
Sex= "Female"
},
};
and invoke the method as GetXElements<Employee>(col,"Employees")
I am expecting to get a XML like below
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee>
<FirstName>John</FirstName>
<Sex>Male</Sex>
</Employee>
<Employee>
<FirstName>Lisa</FirstName>
<Sex>Female</Sex>
</Employee>
<Employees>
I don't think you've understood what the argument to PropertyInfo.GetValue
is meant to be - it's meant to be the target of the property fetch, whereas you're passing in the PropertyInfo
itself.
Additionally, your method only has one parameter, whereas you're trying to pass in two arguments. I think you want something like this:
public static XElement GetXElements<T>(IEnumerable<T> collection, string wrapperName)
where T : class
{
return new XElement(wrapperName, collection.Select(GetXElement));
}
private static XElement GetXElement<T>(T item)
{
return new XElement(typeof(T).Name,
typeof(T).GetProperties()
.Select(prop => new XElement(prop.Name, prop.GetValue(item, null));
}
That gives the result you're looking for. Note that you don't need to specify the type argument when calling GetXElement
, as type inference will do the right thing:
XElement element = GetXElements(col,"Employees");
See more on this question at Stackoverflow