如何将 xml 中的数组反序列化为没有类型属性的不同对象类型?
How to deserialize array in the xml to different object types without type attribute?
Xml 示例:
<Profile>
<ProfileSections>
<ProfileSection Name="Default">
<Email>test@test.com</Email>
<Pasword>test</Pasword>
</ProfileSection>
<ProfileSection Name="Address">
<Street>Undermissed</Street>
</ProfileSection>
</ProfileSections>
</Profile>
如何反序列化此 XML 以将 List ProfileSections 和每个配置文件部分添加到必要的对象?
对象示例:
public class DefaultProdileSection{
[XmlAttribute]
public string Name{ get; set; }
public string Email{ get; set; }
public string PAssword{ get; set; }
}
public class AddressProdileSection{
[XmlAttribute]
public string Name{ get; set; }
public string Street{ get; set; }
}
我们可以在解析时手动将类型属性添加到 xml 令牌流。
如果你真的很想使用反序列化,那么我可以推荐下面的代码。
一组类:
public class Profile
{
public List<ProfileSection> ProfileSections { get; set; }
}
[XmlInclude(typeof(DefaultProfileSection))]
[XmlInclude(typeof(AddressProfileSection))]
public class ProfileSection
{
[XmlAttribute]
public string Name { get; set; }
}
public class DefaultProfileSection : ProfileSection
{
public string Email { get; set; }
public string Password { get; set; }
}
public class AddressProfileSection : ProfileSection
{
public string Street { get; set; }
}
自定义 xml reader 将动态添加必要的信息:
public class TypeAddingXmlReader : XmlTextReader
{
public TypeAddingXmlReader(string url) : base(url) { }
// Define the remaining constructors here
public override string? GetAttribute(string localName, string? namespaceURI)
{
if (base.LocalName == "ProfileSection" &&
localName == "type" &&
namespaceURI == "http://www.w3.org/2001/XMLSchema-instance")
{
var name = base.GetAttribute("Name");
return name switch
{
"Default" => nameof(DefaultProfileSection),
"Address" => nameof(AddressProfileSection)
// add other class names here
};
}
return base.GetAttribute(localName, namespaceURI);
}
}
使用:
var ser = new XmlSerializer(typeof(Profile));
using var reader = new TypeAddingXmlReader("test.xml");
var profile = (Profile)ser.Deserialize(reader);
foreach (var ps in profile.ProfileSections)
Console.WriteLine(ps.Name + " " + ps.GetType());
命名空间:
using System.Xml;
using System.Xml.Serialization;
注意:但我会使用 linq 来 xml 而不会流汗。
Xml 示例:
<Profile>
<ProfileSections>
<ProfileSection Name="Default">
<Email>test@test.com</Email>
<Pasword>test</Pasword>
</ProfileSection>
<ProfileSection Name="Address">
<Street>Undermissed</Street>
</ProfileSection>
</ProfileSections>
</Profile>
如何反序列化此 XML 以将 List ProfileSections 和每个配置文件部分添加到必要的对象? 对象示例:
public class DefaultProdileSection{
[XmlAttribute]
public string Name{ get; set; }
public string Email{ get; set; }
public string PAssword{ get; set; }
}
public class AddressProdileSection{
[XmlAttribute]
public string Name{ get; set; }
public string Street{ get; set; }
}
我们可以在解析时手动将类型属性添加到 xml 令牌流。
如果你真的很想使用反序列化,那么我可以推荐下面的代码。
一组类:
public class Profile
{
public List<ProfileSection> ProfileSections { get; set; }
}
[XmlInclude(typeof(DefaultProfileSection))]
[XmlInclude(typeof(AddressProfileSection))]
public class ProfileSection
{
[XmlAttribute]
public string Name { get; set; }
}
public class DefaultProfileSection : ProfileSection
{
public string Email { get; set; }
public string Password { get; set; }
}
public class AddressProfileSection : ProfileSection
{
public string Street { get; set; }
}
自定义 xml reader 将动态添加必要的信息:
public class TypeAddingXmlReader : XmlTextReader
{
public TypeAddingXmlReader(string url) : base(url) { }
// Define the remaining constructors here
public override string? GetAttribute(string localName, string? namespaceURI)
{
if (base.LocalName == "ProfileSection" &&
localName == "type" &&
namespaceURI == "http://www.w3.org/2001/XMLSchema-instance")
{
var name = base.GetAttribute("Name");
return name switch
{
"Default" => nameof(DefaultProfileSection),
"Address" => nameof(AddressProfileSection)
// add other class names here
};
}
return base.GetAttribute(localName, namespaceURI);
}
}
使用:
var ser = new XmlSerializer(typeof(Profile));
using var reader = new TypeAddingXmlReader("test.xml");
var profile = (Profile)ser.Deserialize(reader);
foreach (var ps in profile.ProfileSections)
Console.WriteLine(ps.Name + " " + ps.GetType());
命名空间:
using System.Xml;
using System.Xml.Serialization;
注意:但我会使用 linq 来 xml 而不会流汗。