Convert XML to Class and Extract XML response to Entity using Generics and Reflection
I just was in need for a simple way to extract XML response and generate a class first from the XML
and then later use this class to extract XML response to Entity using Generics and Reflection
The Power of Generics is that it will reduce the code that can be applied to many response
This for me at least is Alternative and simple than Microsoft XSD tool
I will attach a complete solution that make it easy for you to experiment the new tool.
let us start:
this is basic xml that represent a store :
<?xml version="1.0"?> <response result="good"> <results> <stores count="1"> <store> <SID>4</SID> <Name>St. Michael's Alley</Name> <Twitter>StMichaelsAlley</Twitter> <Facebook></Facebook> <Website>http://www.stmikes.com</Website> <Description> Food Services </Description> <Category>1</Category> <TwitterSearch>Palo Alto Brunch</TwitterSearch> <Reviews> Yelpers love St. Michael's Alley, giving it 4 out of 5 stars </Reviews> <PID>12</PID> <ImageVersion>1</ImageVersion> <SendEmail>0</SendEmail> <Phone>6503262530</Phone> <Street>140 Homer Avenue</Street> <City>Palo Alto</City> <State>CA</State> <Zip>94301</Zip> <ID>7</ID> <Image>http://www.chompon.com/uploads/stores/4.jpg</Image> <ImageSmall>http://www.chompon.com/uploads/stores/4_s.jpg</ImageSmall> </store> </stores> </results> </response>
so we need first to convert this store to class and save it to our project
cause we will use it later to Extract the XML Response:
public string ConvertXMLToClass(string XML, string Tag) { XmlDocument document = new XmlDocument(); document.LoadXml(XML); //Gets all the tags with tag name row XmlNodeList nodeList = document.GetElementsByTagName(Tag); //Loop through each and every node StringBuilder sb = new StringBuilder(); sb.Append("public ").Append(Tag).Append("\r\n{\r\n"); foreach (XmlNode node in nodeList) { foreach (XmlNode xmlAtr in node.ChildNodes) { sb.Append("\tpublic string " + xmlAtr.Name + " {get;set;}\r\n"); } sb.Append("}"); } return sb.ToString(); }
so now we had converted it to a class that you can save it to your project to use it for next step
Note: You can see how to create Objects and fill it from source text at run time if you need this
Now we are ready to extract the XML response , this is basic XML response that represent stores:
<?xml version="1.0"?> <response result="good"> <results> <stores count="2"> <store> <SID>4</SID> <Name>St. Michael's Alley</Name> <Twitter>StMichaelsAlley</Twitter> ...... </store> <store> <SID>5</SID> <Name>Glendon Shop</Name> <Twitter>GLS</Twitter> ...... </store>
... </stores> </results> </response>
Now let us see the power of Generics and Reflection to extract the data and fill our Entity:
public List<T> Parse<T>(string XMLResponse) where T : new() { List<T> tObjects = new List<T>(); XmlDocument document = new XmlDocument(); document.LoadXml(XMLResponse); //Gets all the tags with tag name row XmlNodeList nodeList = document.GetElementsByTagName(new T().GetType().Name.ToLower()); //Loop through each and every node foreach (XmlNode node in nodeList) { T tObject = new T(); foreach (XmlNode xmlAtr in node.ChildNodes) { tObject.GetType().GetProperty(xmlAtr.Name).SetValue(tObject, xmlAtr.InnerText, null); } tObjects.Add(tObject); } //now objectList has your required values. return tObjects; }
As you can see here we can use the same function for many response which worth it actually the C# team
introduce where T : new() , which make it possible for us to create an Object from unknown type at
compile time to be able to use it at run time to fill it.
I hope this find a way to introduce ideas of the power of Generics and Reflection.
If you like it or have any suggestions kindly leave me a comment.