1

I need to deserialize an XML file with known elements in unknown order and count:

<?xml version="1.0" encoding="utf-8"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ConfigType1 Label="abc">
      :
  </ConfigType1>
  <ConfigType1 Label="def">
      :
  </ConfigType1>
  <ConfigType3 Label="ghi"/>
      :
  </ConfigType3>
  <ConfigType1 Label="jkl">
      :
  </ConfigType1>
  <ConfigType2 Label="mno">
      :
  </ConfigType2>
  <ConfigType3 Label="pqr">
      :
  </ConfigType3>
      :
</Config>

My approach is that for each element type there is a class that can serialize and deserialize itself. MyXmlSerializerFactory calls Deserialize() of the corresponding element class depending on the element type.

Am I on the right way with the following approach? I get an XML element in the OnUnknownElement event. How can this be deserialized in the element class? There is only xmlSerializer.Deserialize() with parameters of type Stream, TextReader and XmlReader, but not XmlElement?

    namespace MyNamespace
    {
        [XmlRoot("Config")]
        public class Config
        {
            private static List<MyConfigElement> _configElements = new();
    
            private Config()
            {
            }
    
            public static Config Deserialize(string path)
            {
                Config config;
    
                XmlDeserializationEvents deserializationEvents = new XmlDeserializationEvents();
                deserializationEvents.OnUnknownElement += (sender, args) =>
                {
                    XmlElement xmlElement = args.Element;
// => How can I convert XmlElement to Stream, TextReader or XmlReader?
                    _configElements.Add(MyXmlSerializerFactory.Deserialize(???));
                };
    
                var xmlSerializer = new XmlSerializer(typeof(Config));
                using (var stream = new FileStream(path, FileMode.Open))
                using (var xmlReader = XmlReader.Create(stream))
                {
                    config = (Config)xmlSerializer.Deserialize(xmlReader, deserializationEvents);
                    config.Path = path;
                }
    
                return config;
            }

Thank you very much for hints!

Markus F
  • 11
  • 1
  • Either you need to create a custom xml serialize using IXmlserializable interface (see : https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.ixmlserializable?view=net-7.0&force_isolation=true) or parse with a library method like XDocument or XmlDocument. – jdweng Jun 08 '23 at 09:57
  • That schema doesn’t look like it was designed to be parsed. I wonder if it would be more practical to back up and redesign it rather than putting in all the effort it will take to work with it? – padeso Jun 08 '23 at 11:20
  • Do your ConfigType* types have the same set of properties? If yes, then take a look at https://stackoverflow.com/a/67035760/5045688 – Alexander Petrov Jun 08 '23 at 13:44
  • Is there a fixed set of `` element names? If so, that looks like a sequence of choice elements, and can be deserialized to some `List` property as shown in [Keep sort when deserialize and serialize XML using XmlSerializer](https://stackoverflow.com/q/48096673/3744182) or [Xml Deserialization - Merging two elements into a single `List` object](https://stackoverflow.com/a/37309127/3744182). – dbc Jun 09 '23 at 01:04
  • 1
    Thank you for your hints! I was able to solve the problem with the following approach: https://stackoverflow.com/questions/48096673/keep-sort-when-deserialize-and-serialize-xml-using-xmlserializer – Markus F Jun 14 '23 at 11:00
  • @MarkusF - you're welcome, glad to help! – dbc Jun 14 '23 at 15:45

0 Answers0