Search code examples
c#xmldeserializationxmlserializerxml-attribute

XmlSerializer in C#, deserialize a class decorated with multiple XmlElement with same name by a particular attribute?


I have a class which is decorated with XmlElement in a wrong way, but it has also attributes that could allow me to identify the fields I need.

I can only modify [IWantToSerializeThisAttribute] and add other attributes to MySerializableClass because any modification to property names or XmlElement names would involve heavy coding maintenance.

Here's how the class has been defined:

 [XmlRoot("ARandomXmlRoot")]
    public class MySerializableClass
    {

        //CAMPI DIR_DOCUMENTI
        //[MetadatoDocumentoAlfresco] è un attributo che serve per selezionare i campi per l'aggiornamento dati massivo su alfresco
        [IWantToSerializeThisAttribute]
        [XmlElement("DocumentCode")]
        public string DOC_CODE { get; set; }

        [IWantToSerializeThisAttribute]
        [XmlElement("DocumentId")]
        public string DOC_ID { get; set; }

        [XmlElement("DocumentCode")]
        public string DOC_CODE_FOR_EMPLOYEES { get; set; }

        [XmlElement("DocumentId")]
        public string DOC_ID_FOR_EMPLOYEES { get; set; }

    }

Now, if I do

XmlSerializer.Deserialize(xmlString, typeof(MySerializableClass));

I will get an error most probably because XmlSerializer is finding 2 times the

[XmlElement("DocumentCode")]

and sees it's a duplicate tag.

Anyway I have an

[IWantToSerializeThisAttribute]

that makes the 2 properties different.

Can I tell someway XmlSerializer.Deserialize to catch and valorize only the "IwantToSerializeThisAttribute" properties and ignore the others?

I cannot change serialization with XmlOverrideAttributes, but maybe there is some way to do it during deserialization.

Thanks everyone


Solution

  • Try with XmlOverrideAttributes and Reflection. Using LINQ just to make it short.

    This worked for me:

     string XmlString = "<ARandomXmlRoot> XML HERE </ARandomXmlRoot>";
                XmlAttributeOverrides overrides = new XmlAttributeOverrides();
    
                //Select fields I DON'T WANT TO SERIALIZE because they throw exception
                string[] properties = (new MySerializableClass())
                    .GetType().GetProperties()
                    .Where(p => !Attribute.IsDefined(p, typeof(IWantToSerializeThisAttribute)))
                    .Select(p => p.Name);
    
                //Add an XmlIgnore attribute to them
                properties.ToList().ForEach(field => overrides.Add(typeof(MySerializableClass), field, new XmlAttributes() { XmlIgnore = true }));
    
                MySerializableClass doc = new MySerializableClass();
    
                XmlSerializer serializerObj = new XmlSerializer(typeof(MySerializableClass), overrides);
                using (StringReader reader = new StringReader(xmlString))
                {
                    doc = (MySerializableClass)serializerObj.Deserialize(reader);
                };
    

    Cheers