Lui*_*oza 15 c# xml xml-deserialization
我有一个客户端应用程序提供给我的C#应用程序的XML文档.这是客户端发送XML文件的方式:
<?xml version="1.0" encoding="utf-8"?>
<SomeAccount>
<parentId>2380983</parentId>
<!-- more elements -->
</SomeAccount>
Run Code Online (Sandbox Code Playgroud)
还有一个支持XML反序列化的C#类:
[XmlRoot]
public class SomeAccount
{
[XmlElement("parentId")]
public long ParentId { get; set; }
//rest of fields...
}
Run Code Online (Sandbox Code Playgroud)
但是有一些客户端的系统以这种方式发送XML(请注意大写LeParentId):
<?xml version="1.0" encoding="utf-8"?>
<SomeAccount>
<LeParentId>2380983</LeParentId>
<!-- similar for the other elements -->
</SomeAccount>
Run Code Online (Sandbox Code Playgroud)
如何使这个字段(和其他字段)支持XML名称parentId和LeParentId?
这是我目前用于XML反序列化的方法:
public sealed class XmlSerializationUtil
{
public static T Deserialize<T>(string xml)
{
if (xml == null)
return default(T);
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringReader stringReader = new StringReader(xml);
return (T)serializer.Deserialize(stringReader);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试[XmlElement]在字段中添加两次,每个元素名称一次,但这不起作用.
Bar*_*kin 16
Take 2 - 让我们自己使用未知元素处理事件来实现它(尽管有一些限制,请参阅下面的注释):
public class XmlSynonymDeserializer : XmlSerializer
{
public class SynonymsAttribute : Attribute
{
public readonly ISet<string> Names;
public SynonymsAttribute(params string[] names)
{
this.Names = new HashSet<string>(names);
}
public static MemberInfo GetMember(object obj, string name)
{
Type type = obj.GetType();
var result = type.GetProperty(name);
if (result != null)
return result;
foreach (MemberInfo member in type.GetProperties().Cast<MemberInfo>().Union(type.GetFields()))
foreach (var attr in member.GetCustomAttributes(typeof(SynonymsAttribute), true))
if (attr is SynonymsAttribute && ((SynonymsAttribute)attr).Names.Contains(name))
return member;
return null;
}
}
public XmlSynonymDeserializer(Type type)
: base(type)
{
this.UnknownElement += this.SynonymHandler;
}
public XmlSynonymDeserializer(Type type, XmlRootAttribute root)
: base(type, root)
{
this.UnknownElement += this.SynonymHandler;
}
protected void SynonymHandler(object sender, XmlElementEventArgs e)
{
var member = SynonymsAttribute.GetMember(e.ObjectBeingDeserialized, e.Element.Name);
Type memberType;
if (member != null && member is FieldInfo)
memberType = ((FieldInfo)member).FieldType;
else if (member != null && member is PropertyInfo)
memberType = ((PropertyInfo)member).PropertyType;
else
return;
if (member != null)
{
object value;
XmlSynonymDeserializer serializer = new XmlSynonymDeserializer(memberType, new XmlRootAttribute(e.Element.Name));
using (System.IO.StringReader reader = new System.IO.StringReader(e.Element.OuterXml))
value = serializer.Deserialize(reader);
if (member is FieldInfo)
((FieldInfo)member).SetValue(e.ObjectBeingDeserialized, value);
else if (member is PropertyInfo)
((PropertyInfo)member).SetValue(e.ObjectBeingDeserialized, value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在这个类的实际代码是:
[XmlRoot]
public class SomeAccount
{
[XmlElement("parentId")]
[XmlSynonymDeserializer.Synonyms("LeParentId", "AnotherGreatName")]
public long ParentId { get; set; }
//rest of fields...
}
Run Code Online (Sandbox Code Playgroud)
要反序列化,只需使用XmlSynonymDeserializer而不是常规XmlSerializer.这应该适用于大多数基本需求.
已知限制:
如果您只需要一个名字,这是一个快速(而且很丑陋)的解决方案,在我们只需要读取XML的情况下,在几种情况下我们就将其部署了(这对于序列化回XML来说是有问题的),因为最简单易懂:
[XmlRoot]
public class SomeAccount
{
[XmlElement("parentId")]
public long ParentId { get; set; }
[XmlElement("LeParentId")]
public long LeParentId { get { return this.ParentId; } set { this.ParentId = value; } }
//rest of fields...
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我知道这是一篇过时的文章,但这也许可以帮助其他有相同问题的人。您可以使用此问题的是XmlChoiceIdentifier。
[XmlRoot]
public class SomeAccount
{
[XmlIgnore]
public ItemChoiceType EnumType;
[XmlChoiceIdentifier("EnumType")]
[XmlElement("LeParentId")]
[XmlElement("parentId")]
public long ParentId { get; set; }
//rest of fields...
}
[XmlType(IncludeInSchema = false)]
public enum ItemChoiceType
{
LeParentId,
parentId
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您具有新的xml版本和新的XmlElement名称,则只需将该名称添加到ItemChoiceType枚举中,并将新的XmlElement添加到属性中。
| 归档时间: |
|
| 查看次数: |
8315 次 |
| 最近记录: |