Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using XmlSerializer with an array in the root element

I have an XML document similar to the following:

<scan_details>     <object name="C:\Users\MyUser\Documents\Target1.doc">         ...     </object>     <object name="C:\Users\MyUser\Documents\Target2.doc">         ...     </object>     ... </scan_details> 

I am hoping to use the System.Xml.Serialization attributes to simplify XML deserialization. The issue I have is I cannot work out how to specify that the root node contains an array.

I have tried creating the following classes:

[XmlRoot("scan_details")] public class ScanDetails {     [XmlArray("object")]     public ScanDetail[] Items { get; set; } }  public class ScanDetail {     [XmlAttribute("name")]     public string Filename { get; set; } } 

However when I deserialize the XML into the ScanDetails object the Items array remains null.

How do I deserialize an array in a root node?

like image 511
Hand-E-Food Avatar asked Oct 16 '12 22:10

Hand-E-Food


People also ask

Can I make XmlSerializer ignore the namespace on Deserialization?

Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.

How does the XmlSerializer work C#?

The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.

Why do we use XmlSerializer class?

XmlSerializer enables you to control how objects are encoded into XML. The XmlSerializer enables you to control how objects are encoded into XML, it has a number of constructors.


1 Answers

You should use [XmlElement], and not [XmlArray] to decorate the Items property - it's already an array, and you only want to set the element name.

public class StackOverflow_12924221 {     [XmlRoot("scan_details")]     public class ScanDetails     {         [XmlElement("object")]         public ScanDetail[] Items { get; set; }     }      public class ScanDetail     {         [XmlAttribute("name")]         public string Filename { get; set; }     }      const string XML = @"<scan_details>                              <object name=""C:\Users\MyUser\Documents\Target1.doc"">                              </object>                              <object name=""C:\Users\MyUser\Documents\Target2.doc"">                              </object>                          </scan_details> ";      public static void Test()     {         XmlSerializer xs = new XmlSerializer(typeof(ScanDetails));         MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));         var obj = xs.Deserialize(ms) as ScanDetails;         foreach (var sd in obj.Items)         {             Console.WriteLine(sd.Filename);         }     } } 
like image 71
carlosfigueira Avatar answered Sep 18 '22 12:09

carlosfigueira