鉴于此XML,我需要将其反序列化为类。我不确定如何区分不同类型的两个'MealPeriod'元素,但名称相同。
<SalesSummary>
<MealPeriod1>Lunch</MealPeriod1>
<MealPeriod1Sales>6447.58</MealPeriod1Sales>
<MealPeriod2>Dinner</MealPeriod2>
<MealPeriod2Sales>12074.04</MealPeriod2Sales>
<MealPeriod3>Late-Night</MealPeriod3>
<MealPeriod3Sales>5156.90</MealPeriod3Sales>
<MealPeriod4></MealPeriod4>
<MealPeriod4Sales>0.00</MealPeriod4Sales>
<MealPeriod1>
<Interval>
<Name>10:00am-11:00am</Name>
<Checks>1</Checks>
<Guests>1</Guests>
<AvgCheck>$31.50</AvgCheck>
<AvgGuest>$31.50</AvgGuest>
<Sales>$31.50</Sales>
</Interval>
<Interval>
<Name>11:00am-12:00pm</Name>
<Checks>8</Checks>
<Guests>29</Guests>
<AvgCheck>$85.22</AvgCheck>
<AvgGuest>$23.51</AvgGuest>
<Sales>$681.75</Sales>
</Interval>
<Interval>
<Name>12:00pm-01:00pm</Name>
<Checks>27</Checks>
<Guests>53</Guests>
<AvgCheck>$48.76</AvgCheck>
<AvgGuest>$24.84</AvgGuest>
<Sales>$1,316.58</Sales>
</Interval>
<Interval>
<Name>01:00pm-02:00pm</Name>
<Checks>17</Checks>
<Guests>35</Guests>
<AvgCheck>$58.76</AvgCheck>
<AvgGuest>$28.54</AvgGuest>
<Sales>$999.00</Sales>
</Interval>
<Interval>
<Name>02:00pm-03:00pm</Name>
<Checks>22</Checks>
<Guests>31</Guests>
<AvgCheck>$38.99</AvgCheck>
<AvgGuest>$27.67</AvgGuest>
<Sales>$857.75</Sales>
</Interval>
<Interval>
<Name>03:00pm-04:00pm</Name>
<Checks>21</Checks>
<Guests>44</Guests>
<AvgCheck>$33.76</AvgCheck>
<AvgGuest>$16.11</AvgGuest>
<Sales>$709.00</Sales>
</Interval>
<Interval>
<Name>04:00pm-05:00pm</Name>
<Checks>32</Checks>
<Guests>55</Guests>
<AvgCheck>$57.88</AvgCheck>
<AvgGuest>$33.67</AvgGuest>
<Sales>$1,852.00</Sales>
</Interval>
<Totals>
<Checks>128</Checks>
<Guests>248</Guests>
<AvgCheck>$50.37</AvgCheck>
<AvgGuest>$26.00</AvgGuest>
<Sales>$6,447.58</Sales>
</Totals>
</MealPeriod1>
<MealPeriod2>
<Interval>
<Name>05:00pm-06:00pm</Name>
<Checks>36</Checks>
<Guests>71</Guests>
<AvgCheck>$47.85</AvgCheck>
<AvgGuest>$24.26</AvgGuest>
<Sales>$1,722.75</Sales>
</Interval>
<Interval>
<Name>06:00pm-07:00pm</Name>
<Checks>40</Checks>
<Guests>79</Guests>
<AvgCheck>$49.01</AvgCheck>
<AvgGuest>$24.81</AvgGuest>
<Sales>$1,960.25</Sales>
</Interval>
<Interval>
<Name>07:00pm-08:00pm</Name>
<Checks>46</Checks>
<Guests>82</Guests>
<AvgCheck>$51.03</AvgCheck>
<AvgGuest>$28.63</AvgGuest>
<Sales>$2,347.29</Sales>
</Interval>
<Interval>
<Name>08:00pm-09:00pm</Name>
<Checks>53</Checks>
<Guests>80</Guests>
<AvgCheck>$42.04</AvgCheck>
<AvgGuest>$27.85</AvgGuest>
<Sales>$2,228.25</Sales>
</Interval>
<Interval>
<Name>09:00pm-10:00pm</Name>
<Checks>39</Checks>
<Guests>68</Guests>
<AvgCheck>$46.94</AvgCheck>
<AvgGuest>$26.92</AvgGuest>
<Sales>$1,830.50</Sales>
</Interval>
<Interval>
<Name>10:00pm-11:00pm</Name>
<Checks>39</Checks>
<Guests>56</Guests>
<AvgCheck>$50.90</AvgCheck>
<AvgGuest>$35.45</AvgGuest>
<Sales>$1,985.00</Sales>
</Interval>
<Totals>
<Checks>253</Checks>
<Guests>436</Guests>
<AvgCheck>$47.72</AvgCheck>
<AvgGuest>$27.69</AvgGuest>
<Sales>$12,074.04</Sales>
</Totals>
</MealPeriod2>
<MealPeriod3>
<Interval>
<Name>11:00pm-12:00am</Name>
<Checks>35</Checks>
<Guests>54</Guests>
<AvgCheck>$35.80</AvgCheck>
<AvgGuest>$23.20</AvgGuest>
<Sales>$1,253.04</Sales>
</Interval>
<Interval>
<Name>12:00am-01:00am</Name>
<Checks>34</Checks>
<Guests>45</Guests>
<AvgCheck>$38.21</AvgCheck>
<AvgGuest>$28.87</AvgGuest>
<Sales>$1,299.16</Sales>
</Interval>
<Interval>
<Name>01:00am-02:00am</Name>
<Checks>23</Checks>
<Guests>45</Guests>
<AvgCheck>$40.30</AvgCheck>
<AvgGuest>$20.60</AvgGuest>
<Sales>$926.87</Sales>
</Interval>
<Interval>
<Name>02:00am-03:00am</Name>
<Checks>30</Checks>
<Guests>59</Guests>
<AvgCheck>$48.38</AvgCheck>
<AvgGuest>$24.60</AvgGuest>
<Sales>$1,451.33</Sales>
</Interval>
<Interval>
<Name>03:00am-04:00am</Name>
<Checks>1</Checks>
<Guests>6</Guests>
<AvgCheck>$226.50</AvgCheck>
<AvgGuest>$37.75</AvgGuest>
<Sales>$226.50</Sales>
</Interval>
<Totals>
<Checks>123</Checks>
<Guests>209</Guests>
<AvgCheck>$41.93</AvgCheck>
<AvgGuest>$24.67</AvgGuest>
<Sales>$5,156.90</Sales>
</Totals>
</MealPeriod3>
</SalesSummary>
到目前为止,这是我的课程。使用具有相同名称的多个XmlElement属性是行不通的,但我不确定如何以一种方式装饰类属性。任何指针都将非常感激。谢谢!
public partial class SalesSummary
{
[XmlElement("MealPeriod1")]
public List<SalesSummaryMealPeriod1> MealPeriod1List { get; set; }
[XmlElement("MealPeriod1")]
public string MealPeriod1 { get; set; }
[XmlElement("MealPeriod1Sales")]
public string MealPeriod1Sales { get; set; }
[XmlElement("MealPeriod2")]
public List<SalesSummaryMealPeriod2> MealPeriod2List { get; set; }
[XmlElement("MealPeriod2")]
public string MealPeriod2 { get; set; }
[XmlElement("MealPeriod2Sales")]
public string MealPeriod2Sales { get; set; }
[XmlElement("MealPeriod3")]
public List<SalesSummaryMealPeriod3> MealPeriod3List { get; set; }
[XmlElement("MealPeriod3")]
public string MealPeriod3 { get; set; }
[XmlElement("MealPeriod3Sales")]
public string MealPeriod3Sales { get; set; }
[XmlElement("MealPeriod4")]
public List<SalesSummaryMealPeriod4> MealPeriod4List { get; set; }
[XmlElement("MealPeriod4")]
public string MealPeriod4 { get; set; }
[XmlElement("MealPeriod4Sales")]
public string MealPeriod4Sales { get; set; }
}
请注意,MealPeriodx
元素都已修复。
答案 0 :(得分:0)
您的每个<MealPeriodx>
元素都包含混合内容,并且可能包含:
<Interval>
元素; <Totals>
元素。根据Correct XML serialization and deserialization of "mixed" types in .NET对 Stefan 的回答,您可以将此类元素绑定到c#类型,如下所示:
public class MealPeriod
{
// A polymorphic array of "mixed" types.
// See https://stackoverflow.com/questions/2567414/correct-xml-serialization-and-deserialization-of-mixed-types-in-net
// and the solution by Stefan, https://stackoverflow.com/users/307747/stefan
// for why this works.
[XmlElement("Interval", typeof(Interval))]
[XmlElement("Totals", typeof(Totals))]
[XmlText(typeof(string))]
public List<object> Items { get; set; }
}
public class Interval
{
public string Name { get; set; }
public int Checks { get; set; }
public int Guests { get; set; }
public string AvgCheck { get; set; }
public string AvgGuest { get; set; }
public string Sales { get; set; }
}
public class Totals
{
public int Checks { get; set; }
public int Guests { get; set; }
public string AvgCheck { get; set; }
public string AvgGuest { get; set; }
public string Sales { get; set; }
}
然后,您可以按如下方式定义根对象SalesSummary
,其中每个MealPeriodx
属性必须是 MealPeriod
对象的集合,因为每个<MealPeriodx>
1}}在源XML中多次出现:
public class SalesSummary
{
[XmlElement("MealPeriod1")]
public List<MealPeriod> MealPeriod1 { get; set; }
[XmlElement("MealPeriod1Sales")]
public decimal MealPeriod1Sales { get; set; }
[XmlElement("MealPeriod2")]
public List<MealPeriod> MealPeriod2 { get; set; }
[XmlElement("MealPeriod2Sales")]
public decimal MealPeriod2Sales { get; set; }
[XmlElement("MealPeriod3")]
public List<MealPeriod> MealPeriod3 { get; set; }
[XmlElement("MealPeriod3Sales")]
public decimal MealPeriod3Sales { get; set; }
[XmlElement("MealPeriod4")]
public List<MealPeriod> MealPeriod4 { get; set; }
[XmlElement("MealPeriod4Sales")]
public decimal MealPeriod4Sales { get; set; }
}
public static class MealPeriodExtensions
{
public static string MealPeriodName(this IEnumerable<MealPeriod> mealPeriods)
{
if (mealPeriods == null)
return null;
return String.Concat(mealPeriods.Where(m => m.Items != null).SelectMany(m => m.Items).OfType<string>());
}
public static IEnumerable<T> MealPeriodItems<T>(this IEnumerable<MealPeriod> mealPeriods)
{
if (mealPeriods == null)
return Enumerable.Empty<T>();
return mealPeriods.Where(m => m.Items != null).SelectMany(m => m.Items).OfType<T>();
}
}
然后,给出反序列化辅助方法,如
public static class XmlSerializationHelper
{
public static T LoadFromXml<T>(this string xmlString, XmlSerializer serial = null)
{
serial = serial ?? new XmlSerializer(typeof(T));
using (var reader = new StringReader(xmlString))
{
return (T)serial.Deserialize(reader);
}
}
}
你可以这样做:
var summary = xml.LoadFromXml<SalesSummary>();
// Prints:
// MealPeriod1 name: "Lunch"
Console.WriteLine("MealPeriod1 name: \"{0}\"", summary.MealPeriod1.MealPeriodName());
// Prints
// MealPeriod1 Total Sales: "$6,447.58"
Console.WriteLine("MealPeriod1 Total Sales: \"{0}\"", summary.MealPeriod1.MealPeriodItems<Totals>().Single().Sales);
注意:
如果您将SalesSummary
重新序列化为XML,则两个<MealPeriodx>
元素将被移位以彼此相邻。除了implementing IXmlSerializable
之外,没有简单的方法可以使用XmlSerializer
或this answer手动构建[XmlAnyElement]
代理数组。
幸运的是,您的问题只是要求反序列化。
Interval
和Totals
有许多常见属性,因此您可能希望让它们共享公共基类或接口。
示例工作.Net小提琴here。