Typeof(T). Name; var serializer = new XmlSerializer(typeof(T)); return from item in XDocument. Load(fileName).
Descendants(descendentNodeName) select (T)serializer. Deserialize(item.CreateReader()); } Then, to get your list: var products = XmlSerializerUtils. DeserializeMany(fileName).ToList().
– Dave White Nov 9 '10 at 16:22 Because, with LINQ, you have to create custom code for each different type of object. This would work for different objects as well. – Jordão Nov 9 '10 at 16:26 @Jordao - You're already creating custom code looking for "Product" nodes in the root and casting the output of the serializer to Product so I don't see the value in using the serializer.
The only thing you've achieved is having the serializer new up the Product object for you and that isn't obvious looking at the code. – Dave White Nov 9 '10 at 16:30 I've added a more general method there.... It's the same code, only parameterized. With only LINQ, you'd need different code for different classes.
Also, if your class changes, you'd need to update the code. You see, this solution is more maintainable, and if you're already using the xml serializer, it's a better path to take. – Jordão Nov 9 '10 at 16:31 With the generic, parameterized version, I can see the value in what your doing.
+1 You should remove the non-generic version. – Dave White Nov 9 '10 at 16:38.
There's a quick-and-dirty way to accomplish what you want - simply replace "MyProducts" with something the BCL classes are happy with - ArrayOfProduct: string xml = @" "; //secret sauce: xml = xml. Replace("MyProducts>", "ArrayOfProduct>"); IList myProducts; using (StringReader sr = new StringReader(xml)) { XmlSerializer xs = new XmlSerializer(typeof(List)); myProducts = xs. Deserialize(sr) as IList; } foreach (Product myProduct in myProducts) { Console.
Write(myProduct. Name); } Of course, the right way would be to transform the XML document to replace the MyProducts nodes appropriately - instead of using a string replace - but this illustrates the point.
– Rex M Nov 9 '10 at 16:25 1 I didn't DV your answer, but I don't like the idea of manipulating the source XML document the way that you are, or recommending that someone manipulate the source XML document in order to make their code work. – Dave White Nov 9 '10 at 16:31 @Dave I think you misunderstand the answer. Intermediate transformations to get data from one format to another is pretty common, and as I stated at the end the string replace is to illustrate the point in a simple way.
– Rex M Nov 9 '10 at 16:36 I didn't misunderstand your answer. I just didn't see the manipulation of the source XML document as necessary.It does work, and demonstrates an understanding of what the XmlSerializer is looking for, it just would not be my preferred solution. – Dave White Nov 9 '10 at 16:46.
I'm not sure you're going to have much success using the XML serializer to accomplish what you need. It may be simpler for you to manually parse out the XML and map them explicitly, e.g. XDocument xml = XDocument. Parse(@" "); foreach(var product in xml.
Descendants(XName. Get("Product"))) { var p = new Product { Name = product. Attribute(XName.
Get("Name")). Value }; // Manipulate your result and add to your collection. } ... public class Product { public string Name { get; set; } } If you're using a file, which you most likely are for your XML, just replace the Parse method on the XDocument w/ Load and the appropriate signature.
I don't think you can instruct the serializer to spit out a IList. The serializer can create a MyProduct collection object and fill it with Products. Which sounds like what you want to do.
You can also use LINQ to query the XML document and create a list of IEnumerable as well. // load from stream if that is the case // this just uses a file for demonstration purposes XDocument doc = XDocument. Load("location_of_source.
Xml"); // select all Product nodes from the root node and create a new Product object using // object initialization syntax var listOfProduct = doc. Descendants("Product") . Select(p => new Product { Name = p.
Attribute("Name"). Value}).
While it's novel to not create the class, doing so saves you a lot of code... You don't even have to use it except when you deserialize. //Products declaration XmlRoot(ElementName = "MyProducts") public class MyProducts : List { } public class Product { XmlAttribute public string Name { get; set; } } ... Test public void DeserializeFromString() { var xml = @" "; IList obj = Serialization. DeserializeFromString(xml); Assert.
IsNotNull(obj); Assert. AreEqual(2, obj. Count); } ... //Deserialization library public static T DeserializeFromString(string serialized) { var byteArray = Encoding.ASCII.
GetBytes(serialized); var memStream = new MemoryStream(byteArray); return Deserialize(memStream); } public static T Deserialize(Stream stream) { var xs = new XmlSerializer(typeof(T)); return (T) xs. Deserialize(stream); }.
The problem is that IList is not serializable so you'd have to implement your custom XmlSerializer - walk through xml nodes etc, you can however deserialize your collection into List using out of the box XmlSerializer. Don't forget to add default constructor to your Product Class. XmlSerializer serializer = new XmlSerializer(typeof(List)); FileStream stream = new FileStream(fileName, FileMode.
Open); var product = serializer. Deserialize(sream) as List.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.