0

I have a XML file, with a structure like

<items>
  <item>
    <someDetail>
      A value here
     </someDetail>
  </item>
  <item>
    <someDetail>
      Another value here
     </someDetail>
  </item>
</items>

With multiple items in it.

I want to deserialize the XML on session start ideally, to turn the XML data to objects based on a class (c# asp.net 4)

I have tried several ways with either no success, or a solution which seems clunky and inelegant.

What would people suggest?

I have tried using the xsd.exe tool, and have tried with the xml reader class, as well as usin XElement class to loop through the xml and then create new someObject(props).

These maybe the best and/or only way, but with it being so easy for database sources using the entities framework, I wondered if there was a similar way to do the same but from a xml source.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
atmd
  • 7,430
  • 2
  • 33
  • 64
  • 4
    "I have tried several ways" - such as? Can you please enumerate them and explain why they were a no go? I don't want to suggest stuff that you have already rejected. – Oded Apr 11 '12 at 18:08
  • There are already some good posts on this. You can check out: http://stackoverflow.com/questions/3187444/c-sharp-convert-xml-string-to-object – KingOfHypocrites Apr 11 '12 at 18:17
  • Hi, the above link was one of 2 posts on SO that I saw using the xsd tools. Just wondering if there isn't anything better out there. This is more of a best practice/optimal solution question, rather than a simple 'how to' – atmd Apr 11 '12 at 18:21

3 Answers3

2

The best way to deserialize XML it to create a class that corresponds to the XML structure into which the XML data will deserialize.

The latest serialization technology uses Data Contracts and the DataContractSerializer.

You decorate the class I mentioned above with DataMember and DataItem attributes and user the serializer to deserialize.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
1

I'd use directly the .NET XML serialization - classes declarations:

public class Item {

  [XmlElement("someDetail")]
  public string SomeDetail;

} // class Item


[XmlRoot("items")]
public class MyData {

  [XmlElement("item")]
  public List<Item> Items;

  public static MyData Deserialize(Stream source)
  {
    XmlSerializer serializer = new XmlSerializer(typeof(MyData));
    return serializer.Deserialize(source) as MyData;
  } // Deserialize

} // class MyData

and then to read the XML:

  using (FileStream fs = new FileStream(@"c:\temp\items.xml", FileMode.Open, FileAccess.Read)) {
    MyData myData = MyData.Deserialize(fs);
  }
MiMo
  • 11,793
  • 1
  • 33
  • 48
  • `XmlSerializer` is old and the newer `DataContractSerializer` give you more control. – Oded Apr 11 '12 at 18:25
  • I am used to `XmlSerializer` and it works OK - I did not find (yet?) a compelling reason to try something different. – MiMo Apr 11 '12 at 18:29
  • One good reason is when you need several different serialization formats - XML and JSON for instance. Easy to do with `DataContractSerializer`, not so much with `XmlSerializer`. – Oded Apr 11 '12 at 18:31
  • @Oded, thanks for that info - i don't know how I would have ever learned about it otherwise - incedentally, how do you tie its name to its functionality (in other words how do I remember this)? – Aaron Anodide Apr 12 '12 at 16:10
  • @Oded, ok and it happens to be a better general purpose xml serializer is what your getting at. I understand. – Aaron Anodide Apr 12 '12 at 17:12
  • @Gabriel - It gives you better control over serialization and deserialization and supports XML _and_ JSON. – Oded Apr 12 '12 at 18:05
1

I've concluded is there is not simple unified mechanism (probably due to the inherent complexities involved with non trivial cases - this question always crops up in the context of simple scenarios like your example xml).

Xml serialization is pretty easy to use. For your example, you would just have to create a class to contain a items and another class for the actual item. You might have to apply some attributes to get everything to work correctly, but the coding will not be much. Then it's as easy as -

var serializer = new XmlSerializer(typeof(ItemsContainer));
var items = serializer.Deserialize(...) as ItemsContainer;

Datasets are sometimes considered "yesterday tech" but I use them when they solve the problem well, and you can leverage the designer. The generated code is not pretty but the bottom line is you can persist to a database via the auto generated adapters and to XML using a method right on the data set. You can read it in this way as well.

XSD.exe isn't that bad once you get used to it. I printed the help to a text file and included it in my solutions for a while. When you use the /c option to create classes, you get clean code that can be used with the XmlSerialzier.

Visual Studio 2010 (maybe other versions too) has an XML menu which appears when you have an Xml file open and from that you can also generate an XSD from sample Xml. So in a couple of steps you could take your example xml and generate the XSD, then run it through XSD.exe and use the generated classes with a couple of lines XmlSerializer code... it feels like a lot of machinations but you get used to it.

Aaron Anodide
  • 16,906
  • 15
  • 62
  • 121