user2161341
user2161341

Reputation: 59

Deserialize different element tags into one object class?

I have the this form of xml

<Element attributeX="X" attributeY="Y"> 
  <SubElement attributeX="X" attributeZ="Z"/>
</Element>
<Element attributeX="X" attributeY="Y"> 
  <SubElement attributeX="X" attributeZ="Z"/>
  <Element attributeX="X" attributeY="Y">
    <SubElement attributeX="X" attributeZ="Z"/>
  </Element>
</Element>

but in the code I have one object class for "Element" and "SubElement" with attributes "attributeY" "attributeX" and "attributeZ", I cannot find a way to do the deserialisation of the XML ?

Ia wan to add that y exmaple is different from the links you gave me. In fact here is the class that I have in my code

public class Element
{
  public type1 attributeX;
  public type1 attributeY;
  public type1 attributeZ;

  public observableCollection<Element> Elements;
}

and in the xml file I have different tags : * SubElement when I have attributeZ *Element when I have attributeY

So when oing the desrialisation "Element" and "subElement" should have the same class type "Element"

Upvotes: 0

Views: 258

Answers (2)

acelent
acelent

Reputation: 8135

The following example might be a good start on your journey:

public class Element
{
    [XmlAttribute]
    public type1 attributeX { get; set; }

    [XmlAttribute]
    public type1 attributeY { get; set; }
    [XmlIgnore]
    public bool attributeYSpecified { get { return attributeY != null; } set { } }

    [XmlAttribute]
    public type1 attributeZ { get; set; }
    [XmlIgnore]
    public bool attributeZSpecified { get { return attributeZ != null; } set { } }

    [XmlChoiceIdentifier("ElementTypes")]
    [XmlElement("Element", typeof(Element))]
    [XmlElement("SubElement", typeof(Element))]
    public Element[] Elements { get; set; }

    [XmlIgnore]
    public ElementType[] ElementTypes
    {
        get
        {
            return Elements
                .Select(el => (el.attributeYSpecified && !el.attributeZSpecified) ?
                              ElementType.Element :
                              (!el.attributeYSpecified && el.attributeZSpecified) ?
                              ElementType.SubElement :
                              ElementType.None)
                .ToArray();
        }
        set
        {
        }
    }
}

public enum ElementType
{
    None,
    Element,
    SubElement
}

Note that I defined each *Specified property to look for a null value, but if type1 is a value type, you may need to keep them as simple properties and manually check them after deserialization and set them for proper serialization.

The None enumeration value is on purpose, to make serialization fail when things look weird. However, if you have some sensible default that can have both Y and Z attributes, you may remove it.

Upvotes: 1

Aelphaeis
Aelphaeis

Reputation: 2613

If you have this type of situation I suggest you take a look at the following : http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable(v=vs.110).aspx

This will allow you to manually specific the serialization and serialization algorithm.

You may also use this if its only for xml:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx

Here is an example of how to implement the latter :

http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly

Upvotes: 0

Related Questions