How to use XmlSerializer to serialize collections of objects

Here are the steps I have taken so far to work with the XmlDocument returned by a third-party DLL.

  • I saved the XmlDocument as SegmentationSummary.xml.
  • I used XSD.exe to create SegmentationSummary.xsd.
  • I used XSD.exe to create SegmentationSummary.cs.

Here is an example of SegmentationSummary.cs. Note that ShmResult is the root representation of the node.

/// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "omitted")] [System.Xml.Serialization.XmlRootAttribute(Namespace = "omitted", IsNullable = false)] public partial class ShmResult { private ShmResultDownloadDetail[] downloadDetailField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute("DownloadDetail")] public ShmResultDownloadDetail[] DownloadDetail { get { return this.downloadDetailField; } set { this.downloadDetailField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "omitted")] public partial class ShmResultDownloadDetail { private string modelCodeField; /// <remarks/> public string ModelCode { get { return this.modelCodeField; } set { this.modelCodeField = value; } } } 

Now I wanted to use this to read an XmlDocument and get started with classes in SegmentationSummary.cs. Here is the code I wrote:

 private XmlDocument _document; SegmentationSummary.ShmResult _Result; private void LoadXML() { XmlReader xmlRdr = new XmlNodeReader(_document); System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(SegmentationSummary.ShmResult)); _Result = (SegmentationSummary.ShmResult)s.Deserialize(xmlRdr); } 

When LoadXML () is executed, I get exceptions of this sort:

The SegmentationSummaryHandlerTest.TestMethod1 test method threw an exception: System.InvalidOperationException: Failed to create a temporary class (Result = 1). error CS0030: Could not convert 'MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail [] to' MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail 'error CS0029: implicitly convert.Meter.reloadCermulturetermnterrent AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail [] '

Now in the FAQ on http://msdn.microsoft.com/en-us/library/ms950721.aspx the following is indicated:

Q: How to serialize collections of objects?

A: XmlSerializer throws an exception when the collection contains types that were not declared by the XmlSerializer constructor. You can:

  • Declare types for the serializer by passing type [] with the types expected as part of the collection.

    OR

  • Embed a strongly typed collection obtained from System.Collections.CollectionBase with an indexer matching the Add () method.

My question is: which one is the โ€œbestโ€ and how can I implement this solution?

+4
source share
4 answers

I had a similar problem.

There is a problem with serializing nested unrelated elements. Here is an explanation.

To fix the problem, I removed maxoccurs = "unbounded" from xsd and restored the class file. After that, serialization worked.

+3
source

I always used option 2 , so there might be something like this for you:

 public class ShmResult : List<ShmResultDownloadDetail> { } 
+1
source

Microsoft has a bug. It has been since 2003. I know that the thread is out of date, but for others it hits the head. XSD generation is incorrect. In the above steps, using xsd.exe to generate xsd from xml just doesn't look right. I used a tool called trang ( open source java ), you can create xsd with this. In fact, you can use multiple XML files to create it. Then use xsd.exe to create the .cs file. It worked.

0
source

I had the same problem as you:

  • I made xsd from XML using xsd.exe
  • I generated the class (es) using xsd.exe and the resulting schema from step 1.
  • After trying to use this class as a type for the XMLSerializer constructor, I received this exception message (pseudo message):

System.InvalidOperationException: Unable to create a temporary class (Result = 1). error CS0030: Unable to convert type Type1 [] to Type1.

In addition, xsd.exe created a resulting class that had matrix data types (Type [] []), and in fact this was my main concern.

Once I created an XMLSerializer constructor with an array of types that can be inside a collection, I also modified my xsd file by removing maxoccurs = "unbounded" from several elements in my schema. The new generation process has given me a new class. After trying to use the newly created class in XMLSerializer, everything was fine.

Therefore, I suggest you declare an array of types (types that can be part of the collection), and present it to the XMLSerializer constructor. Also, from your generated schema, remove maxoccurs = "unbounded" from certain elements.

0
source

All Articles