我正在学习XML序列化并遇到问题,我有两个claess
[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和我做错的任何事情时都会出错?
由于
答案 0 :(得分:1)
这是我写的程序
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 :(得分:0)
我遇到了同样的错误。 我没有一个很好的答案,但这就是我所做的:
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());
}
}
// ******************************************************************
}
}