API XmlSerializer
не имеет встроенной функции "слияния", однако: он поддерживает шаблон *Specified
- это означает: если у вас есть:
public string Email { get; set; }
[XmlIgnore]
public bool EmailSpecified { get; set; }
затем EmailSpecified
a: контролирует, сериализуется ли Email
, и b: ему присваивается значение true
при десериализации из активного значения. Итак: вы можете сделать что-то вроде:
public class Account
{
public string Email { get; set; }
[XmlIgnore]
public bool EmailSpecified { get; set; }
public bool Active { get; set; }
[XmlIgnore]
public bool ActiveSpecified { get; set; }
public List<string> Roles { get; set; }
[XmlIgnore]
public bool RolesSpecified { get; set; }
public DateTime CreatedDate { get; set; }
[XmlIgnore]
public bool CreatedDateSpecified { get; set; }
}
, а затем объединить вручную:
Account account = new Account
{
Email = "james@example.com",
Active = true,
CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
Roles = new List<string>
{
"User",
"Admin"
}
};
var xml = @"<Account>
<Active>false</Active>
</Account>";
using (var source = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(Account));
var merge = (Account)serializer.Deserialize(source);
// this bit could also be done via reflection
if (merge.ActiveSpecified)
{
Console.WriteLine("Merging " + nameof(merge.Active));
account.Active = merge.Active;
}
if (merge.EmailSpecified)
{
Console.WriteLine("Merging " + nameof(merge.Email));
account.Email = merge.Email;
}
if (merge.CreatedDateSpecified)
{
Console.WriteLine("Merging " + nameof(merge.CreatedDate));
account.CreatedDate = merge.CreatedDate;
}
if (merge.RolesSpecified)
{
Console.WriteLine("Merging " + nameof(merge.Roles));
account.Roles = merge.Roles;
}
}