簡體   English   中英

XmlSerializer中的未知屬性xsi:type

[英]Unknown attribute xsi:type in XmlSerializer

我正在學習XML序列化並遇到問題,我有兩個抱怨

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

}

public class SubClass : BaseClass
{
}

我正在嘗試將SubClass對象序列化為XML文件,我使用打擊代碼

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

我注意到序列化成功,但是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="SubClass">
...
</Employee>

如果我用

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

我注意到它會抱怨xsi:type是未知屬性(我注冊了一個事件),盡管成功解析了XML中嵌入的所有信息,並且SubClassObject中的成員已正確還原。

有人知道為什么解析xsi:type時出錯,而我做錯了什么嗎?

謝謝

這是我寫的程序

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>

而且有效

我遇到了同樣的錯誤。 我沒有很好的答案,但這是我所做的:

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's 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());
            }

        }

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



    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM