cha*_*nan 5 .net c# serialization
我想将以下XML反序列化/序列化为对象.
<Discounts>
<Discount Type="Voucher" Key="ABCD00001" Percent="2" />
<Discount Type="Quantity">
<Periods>
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" />
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" />
</Periods>
</Discount>
</Discounts>
Run Code Online (Sandbox Code Playgroud)
是否可以让@Type属性定义应该使用哪种类型的对象进行序列化?
例如,在C#中:
[XmlArray]
[XmlArrayItem("Discount",typeof(Voucher)]
[XmlArrayItem("Discount",typeof(Quantity)]
public List<Discount> Discounts { get; set; }
Run Code Online (Sandbox Code Playgroud)
我希望我的解释是有道理的.任何帮助,将不胜感激.谢谢.
Andrew Anderson回答后更新:
这是更新的XML:
<Discounts>
<Discount xsi:Type="Voucher" Key="ABCD00001" Percent="2" />
<Discount xsi:Type="Quantity">
<Periods>
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" />
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" />
</Periods>
</Discount>
</Discounts>
Run Code Online (Sandbox Code Playgroud)
我改变了我的类看起来像这样:
[Serializable]
[XmlInclude(typeof(Voucher))]
[XmlInclude(typeof(Quantity))]
[XmlRoot("Discount")]
public class Discount
{ ... }
public class Quantity : Discount { }
public class Voucher : Discount { }
Run Code Online (Sandbox Code Playgroud)
当我反序列化时,'折扣'列表有两个'折扣'对象.我希望在这一点上列表应该有一个'Quantity'对象和'Voucher'对象.这可能是因为我的列表被定义为只有一个'Discount'对象.以下是我的'折扣'列表对象的代码.
[XmlArray]
[XmlArrayItem("Discount")]
public List<Discount> Discounts { get; set; }
Run Code Online (Sandbox Code Playgroud)
现在的问题是如何设置列表以包含两种不同类型的对象?
如果您可以控制XML,则可以使用XmlIncludeDiscount基类上的属性来处理此问题.
例如(未经测试的代码):
[Serializable]
[XmlInclude(typeof(Voucher))]
[XmlInclude(typeof(Quantity))]
[XmlRoot("Discount")]
public class Discount { }
public class Quantity : Discount { }
public class Voucher : Discount { }
Run Code Online (Sandbox Code Playgroud)
生成的Xml将如下所示:
<Discounts>
<Discount xsi:type="Voucher" Key="ABCD00001" Percent="2" />
<Discount xsi:type="Quantity">
<Periods>
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" />
<Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" />
</Periods>
</Discount>
</Discounts>
Run Code Online (Sandbox Code Playgroud)
更新:
下面是一组示例类和一个控制台应用程序,用于演示此格式的序列化和解除序列.
首先是数据定义:
[Serializable]
public class Shopping
{
[XmlArray]
[XmlArrayItem("Discount")]
public List<Discount> Discounts { get; set; }
}
[Serializable]
[XmlInclude(typeof(Voucher))]
[XmlInclude(typeof(Quantity))]
[XmlRoot("Discount")]
public class Discount
{
public int Amount { get; set; }
}
public class Quantity : Discount
{
public int MyQuantity { get; set; }
}
public class Voucher : Discount
{
public string MyVoucherName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
测试应用程序:
public class Program
{
static void Main(string[] args)
{
XmlSerializer xs = new XmlSerializer(typeof(Shopping));
var myShopping = new Shopping();
myShopping.Discounts = new List<Discount>();
myShopping.Discounts.Add(new Voucher() {MyVoucherName = "Foo", Amount = 6});
myShopping.Discounts.Add(new Quantity() { MyQuantity = 100, Amount = 6 });
StringBuilder xml = new StringBuilder();
XmlWriter xmlWriter = XmlWriter.Create(xml);
xs.Serialize(xmlWriter, myShopping);
Console.WriteLine("Serialized:");
Console.WriteLine(xml);
Console.WriteLine();
Console.WriteLine("Deserialized:");
TextReader tr = new StringReader(xml.ToString());
var myNewShopping = (Shopping) xs.Deserialize(tr);
if (myNewShopping.Discounts != null)
{
foreach (var discount in myNewShopping.Discounts)
{
if (discount is Voucher)
{
var voucher = (Voucher) discount;
Console.WriteLine("Voucher - Amount={0}, Name={1}", voucher.Amount, voucher.MyVoucherName);
}
else if (discount is Quantity)
{
var quantity = (Quantity)discount;
Console.WriteLine("Quantity - Amount={0}, #={1}", quantity.Amount, quantity.MyQuantity);
}
else
{
Console.WriteLine("Discount - Amount={0}", discount.Amount);
}
}
}
else
{
Console.WriteLine("No Discounts found");
}
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5591 次 |
| 最近记录: |