I am facing an issue while deserializing/serializing XML into a C# object. The XML structure has mixed order of elements, and I am encountering problems with elements that have the same name but different purposes. Here's a simplified version of my C# class:
public class Uientry
{
[XmlElement(ElementName = "u")]
public string ID { get; set; }
[XmlElement(ElementName = "s")]
public List<string> Strings { get; set; }
[XmlElement(ElementName = "i")]
public List<string> Integer { get; set; }
[XmlElement(ElementName = "additional_data")]
public Additional_data Additional_data { get; set; }
}
The issue arises when the XML has elements with the same name but different purposes, and their order is not fixed. For example, the <i> elements (representing integers) can appear before and after <s> elements (representing strings), causing conflicts.
Important:I want that the order of the elements stays the same after Serializing
this is some of my xml code
<uientry>
<u>606917248</u><!-- ID (80 d2 2c 24) -->
<s>root</s><!-- title -->
<s>CampaignRoot</s><!-- title2 -->
<i>0</i><!-- x offset -->
<i>0</i><!-- y offset -->
<no /><!-- uientry flag 1 -->
<yes /><!-- uientry flag 2 -->
<byte>1</byte><!-- uientry flag 3 -->
<no /><!-- uientry flag 4 -->
<no /><!-- uientry flag 5 -->
<no /><!-- uientry flag 6 -->
<no /><!-- uientry flag 7 -->
<yes /><!-- uientry flag 8 -->
<no /><!-- uientry flag 9 -->
<no /><!-- uientry flag 10 -->
<no /><!-- uientry flag 11 -->
<no /><!-- uientry flag 12 -->
<yes />
<unicode></unicode><!-- tooltip text -->
<unicode></unicode><!-- tooltip id -->
<i>0</i><!-- 00:00:00:00 --><!-- docking? -->
<i>0</i><!-- 00:00:00:00 --><!-- docking x? -->
<i>0</i><!-- 00:00:00:00 --><!-- docking y? -->
<no />
<i>0</i><!-- default state id -->
<images count="1">
<image>
<u>606535040</u><!-- ID (80 fd 26 24) -->
<s></s><!-- path -->
<i>1280</i><!-- x size -->
<i>960</i><!-- y size -->
<no />
</image>
</images>
<i>0</i><!-- 00:00:00:00 --><!-- mask image? -->
<i>0</i>
<states count="0">
</states>
<children count="0">
</children>
<additional_data type="none" />
</uientry>
How can I modify my C# class or use attributes to handle such a scenario? Is there a way to instruct the XML deserializer to consider the purpose of the element and handle it accordingly?
Your XML has a schema that includes a sequence of choice element. A choice element indicates that one of a fixed set of elements --
<u>,<i>,<yes>,<no>,<unicode>and so on -- will occur in the XML.XmlSerializersupports choice elements as is explained in Choice Element Binding Support:Thus, as explained in this answer to Xml Deserialization - Merging two elements into a single List<T> object, you can either model this as a list of polymorphic types, or a pair of arrays of choice types and values. Personally I think the first option is easier, so let's go with that.
First define some base type
UientryItem, then for every element that might appear in<uientry>, create a subtype corresponding to that element, indicating the name via anXmlTypeAttribute.TypeNameattribute property:Next define
Uientryas follows:And you will be able to deserialize your
<uientry>using anew XmlSerializer(typeof(Uientry))e.g. as follows:And the element order will be preserved via the order of items in the
public List<UientryItem> Items { get; set; }list.Notes:
<uientry>element -- for instance, that<additional_data>always appears last -- then you can capture that with a separate property as you did in your originalUientryclass.Demo fiddle here.