Unknown xsi attribute: enter XmlSerializer

I am learning XML serialization and responding to a problem, I have two claess

[System.Xml.Serialization.XmlInclude(typeof(SubClass))]
public class BaseClass
{

}

public class SubClass : BaseClass
{
}

I am trying to serialize a SubClass object to an XML file, I am using beat code

XmlSerializer xs = new XmlSerializer(typeof(Base));
xs.Serialize(fs, SubClassObject);

I noticed that Serialization was successful, but the XML file is similar to

<?xml version="1.0"?>
<BaseClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="SubClass">
...
</Employee>

If i use

XmlSerializer xs = new XmlSerializer(typeof(Base));
SubClassObject = xs.Deserialize(fs) as SubClass;

I noticed that he would complain about xsi: type is an unknown attribute (I registered an event), although all the information embedded in XML was successfully parsed and the members in SubClassObject were restored correctly.

Does anyone know why an error occurs while parsing xsi: type and something that I did wrong?

thank

+3
source share
2 answers

Here is the program I wrote

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace XmlIncludeExample
{
    [XmlInclude(typeof(DerivedClass))]
    public class BaseClass
    {
        public string ClassName = "Base Class";
    }

    public class DerivedClass : BaseClass
    {
        public string InheritedName = "Derived Class";
    }

    class Program
    {
        static void Main(string[] args)
        {
            string fileName = "Test.xml";
            string fileFullPath = Path.Combine(Path.GetTempPath(), fileName);

            try
            {
                DerivedClass dc = new DerivedClass();

                using (FileStream fs = new FileStream(fileFullPath, FileMode.CreateNew))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(BaseClass));
                    xs.Serialize(fs, dc);
                }

                using (FileStream fs = new FileStream(fileFullPath, FileMode.Open))
                {
                    XmlSerializer xs = new XmlSerializer(typeof(BaseClass));
                    DerivedClass dc2 = xs.Deserialize(fs) as DerivedClass;
                }
            }
            finally
            {
                if (File.Exists(fileFullPath))
                {
                    File.Delete(fileFullPath);
                }
            }
        }
    }
}

xml

<?xml version="1.0" ?> 
- <BaseClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="DerivedClass">
  <ClassName>Base Class</ClassName> 
  <InheritedName>Derived Class</InheritedName> 
  </BaseClass>

+1

. , :

using System;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;

namespace HQ.Util.General
{
    /// <summary>
    /// Save by default as User Data Preferences
    /// </summary>
    public class XmlPersistence
    {
        // ******************************************************************
        public static void Save<T>(T obj, string path = null) where T : class
        {
            if (path == null)
            {
                path = GetDefaultPath(typeof(T));
            }

            var serializer = new XmlSerializer(typeof(T));
            using (TextWriter writer = new StreamWriter(path))
            {
                serializer.Serialize(writer, obj);
                writer.Close();
            }
        }

        // ******************************************************************
        public static T Load<T>(string path = null,
            Action<object, XmlNodeEventArgs> actionUnknownNode = null,
            Action<object, XmlAttributeEventArgs> actionUnknownAttribute = null) where T : class
        {
            T obj = null;

            if (path == null)
            {
                path = GetDefaultPath(typeof(T));
            }

            if (File.Exists(path))
            {
                var serializer = new XmlSerializer(typeof(T));

                if (actionUnknownAttribute == null)
                {
                    actionUnknownAttribute = UnknownAttribute;
                }

                if (actionUnknownNode == null)
                {
                    actionUnknownNode = UnknownNode;
                }

                serializer.UnknownAttribute += new XmlAttributeEventHandler(actionUnknownAttribute);
                serializer.UnknownNode += new XmlNodeEventHandler(actionUnknownNode);

                using (var fs = new FileStream(path, FileMode.Open))
                {
                    // Declares an object variable of the type to be deserialized.
                    // Uses the Deserialize method to restore the object state 
                    // with data from the XML document. */
                    obj = (T)serializer.Deserialize(fs);
                }
            }

            return obj;
        }

        // ******************************************************************
        private static string GetDefaultPath(Type typeOfObjectToSerialize)
        {
            return Path.Combine(AppInfo.AppDataFolder, typeOfObjectToSerialize.Name + ".xml");
        }

        // ******************************************************************
        private static void UnknownAttribute(object sender, XmlAttributeEventArgs xmlAttributeEventArgs)
        {
            // Correction according to: https://stackoverflow.com/questions/42342875/xmlserializer-warns-about-unknown-nodes-attributes-when-deserializing-derived-ty/42407193#42407193
            if (xmlAttributeEventArgs.Attr.Name == "xsi:type")
            {

            }
            else
            {
                throw new XmlException("UnknownAttribute" + xmlAttributeEventArgs.ToString());
            }
        }

        // ******************************************************************
        private static void UnknownNode(object sender, XmlNodeEventArgs xmlNodeEventArgs)
        {
            // Correction according to: https://stackoverflow.com/questions/42342875/xmlserializer-warns-about-unknown-nodes-attributes-when-deserializing-derived-ty/42407193#42407193
            if (xmlNodeEventArgs.Name == "xsi:type")
            {

            }
            else
            {
                throw new XmlException("UnknownNode" + xmlNodeEventArgs.ToString());
            }

        }

        // ******************************************************************



    }
}
0

Source: https://habr.com/ru/post/1743585/


All Articles