如何将内部XML反序列化为对象?

时间:2017-06-26 20:53:21

标签: c# xml unit-testing

我有一个现有的XML文档,我试图映射到C#类。

我还创建了一个单元测试,以确保XML正在被反序列化。

但是,当期望为PageName元素计数为2时,单元测试失败。当我调试时,我看到PageName元素计数为0.同样在调试视图中,各个DeskBroker.Broker元素也有0个计数。

不确定我是否正确设置了XML属性。有人可以检查我的工作,看看我是否使用正确的注释?我确信我错过了一些东西。

谢谢。

这是XML:

<?xml version="1.0" encoding="utf-8"?>
<User>
 <FavoriteQuotePages>
  <Group name="Default">
   <PageName>NG Options</PageName>
   <PageName startdate="today" enddate="today">NG Options</PageName>
  </Group>
  <Group name="CUSTOM PAGES">
   <PageName sourcepagename="NG Options" daterange="TopDay" startdate="today" enddate="today" customfilters="[{&quot;fieldName&quot;:&quot;BidBOEName&quot;, &quot;expr&quot;:&quot;ION&quot;, &quot;cond&quot;:&quot;contains&quot;}]">ION ONLY</PageName>
   <PageName sourcepagename="NG Options" daterange="TopDay" startdate="today" enddate="today" customfilters="[{&quot;fieldName&quot;:&quot;BidBOEName&quot;, &quot;expr&quot;:&quot;CNG&quot;, &quot;cond&quot;:&quot;contains&quot;}]">CIE Only</PageName>
  </Group>
 </FavoriteQuotePages>
 <LayoutSettings>
  <PageDialog id="1" dialogname="market-page-dialog" modelname="MarketPageModel" viewname="_MarketPage" modelkey="" positionx="238.9965362548828" positiony="76.48611450195312" width="1275" height="650" />
 </LayoutSettings>
 <QuoteDefaults Product="NATURAL GAS">
  <ClearingEntities>
   <ID>12</ID>
  </ClearingEntities>
  <Quantity>100</Quantity>
  <ReserveQty></ReserveQty>
  <Timer>3</Timer>
  <DeskBrokers>
   <DeskBroker Desk="2366">
    <Broker Primary="False">2368</Broker>
   </DeskBroker>
   <DeskBroker Desk="2456">
    <Broker Primary="False">2657</Broker>
   </DeskBroker>
   <DeskBroker Desk="2302">
    <Broker Primary="False">2306</Broker>
   </DeskBroker>
   <DeskBroker Desk="2">
    <Broker Primary="False">82</Broker>
   </DeskBroker>
   <DeskBroker Desk="34">
    <Broker Primary="False">89</Broker>
   </DeskBroker>
   <DeskBroker Desk="64">
    <Broker Primary="False">15166</Broker>
   </DeskBroker>
  </DeskBrokers>
 </QuoteDefaults>
</User>

我已将XML定义如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace TestApplication
{
  #region UserPreferences

  [XmlRoot("User")]
  public class UserPreferences
  {
    #region Private Static Members

    private static XmlSerializer m_xmlSerializer = new XmlSerializer(typeof(UserPreferences));

    #endregion

    #region Public Properties

    [XmlArray("FavoriteQuotePages")]
    public List<PageGroup> FavoriteQuotePages { get; set; }

    [XmlArray("LayoutSettings")]
    public List<PageDialogSettings> LayoutSettings { get; set; }

    public QuoteDefaultSettings QuoteDefaults { get; set; }

    #endregion

    #region Constructors

    public UserPreferences()
    {
      FavoriteQuotePages = new List<PageGroup>();
      LayoutSettings = new List<PageDialogSettings>();
      QuoteDefaults = new QuoteDefaultSettings();
    }

    #endregion

    #region XML Serialization Methods

    public static string SerializeFrom(UserPreferences userPreferences)
    {
      try
      {
        XmlSerializerNamespaces xns = new XmlSerializerNamespaces();
        xns.Add(string.Empty, string.Empty);
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        settings.OmitXmlDeclaration = true;
        StringWriter writer = new StringWriter();
        XmlWriter xmlWriter = XmlWriter.Create(writer, settings);
        m_xmlSerializer.Serialize(xmlWriter, userPreferences, xns);
        String xml = writer.ToString();
        return xml;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    public static UserPreferences DeserializeFrom(string xml)
    {
      try
      {
        StringReader reader = new StringReader(xml);
        UserPreferences userPreferences = (UserPreferences)m_xmlSerializer.Deserialize(reader);
        return userPreferences;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    #endregion
  }

  #endregion

  #region PageGroup

  [XmlType("Group")]
  public class PageGroup
  {
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlArray("Group")]
    public List<Page> Pages { get; set; }

    public PageGroup()
    {
      Pages = new List<Page>();
    }
  }

  #endregion

  #region Page

  [XmlType("PageName")]
  public class Page
  {
    [XmlElement]
    public string Name { get; set; }

    [XmlAttribute("startdate")]
    public DateTime StartDate { get; set; }

    [XmlAttribute("enddate")]
    public DateTime EndDate { get; set; }

    [XmlAttribute("daterange")]
    public string DateRange { get; set; }

    [XmlAttribute("customfilters")]
    public string CustomFilters { get; set; }

    [XmlAttribute("sourcepagename")]
    public string SourcePageName { get; set; }
  }

  #endregion

  #region PageDialogSettings

  [XmlType("PageDialog")]
  public class PageDialogSettings
  {
    [XmlAttribute("id")]
    public int Id { get; set; }

    [XmlAttribute("dialogname")]
    public string DialogName { get; set; }

    [XmlAttribute("viewname")]
    public string ViewName { get; set; }

    [XmlAttribute("modelname")]
    public string ModelName { get; set; }

    [XmlAttribute("modelkey")]
    public string ModelKey { get; set; }

    [XmlAttribute("positionx")]
    public double PositionX { get; set; }

    [XmlAttribute("positiony")]
    public double PositionY { get; set; }

    [XmlAttribute("width")]
    public int Width { get; set; }

    [XmlAttribute("height")]
    public int Height { get; set; }
  }

  #endregion

  #region QuoteDefaultSettings

  [XmlType("QuoteDefaults")]
  public class QuoteDefaultSettings
  {
    [XmlAttribute("Product")]
    public string Product { get; set; }

    [XmlElement]
    public int Quantity { get; set; }

    [XmlElement]
    public int ReserveQuantity { get; set; }

    [XmlElement]
    public int Timer { get; set; }

    [XmlArray("ClearingEntities")]
    [XmlArrayItem("ID")]
    public List<long> ClearingEntityIds { get; set; }

    [XmlArray]
    public List<DeskBroker> DeskBrokers { get; set; }

    public QuoteDefaultSettings()
    {
      ClearingEntityIds = new List<long>();
      DeskBrokers = new List<DeskBroker>();
    }
  }

  #endregion

  #region DeskBroker

  [XmlType("DeskBroker")]
  public class DeskBroker
  {
    [XmlAttribute("Desk")]
    public long DeskId { get; set; }

    [XmlArray]
    public List<Broker> Brokers { get; set; }

    public DeskBroker()
    {
      Brokers = new List<Broker>();
    }
  }

  #endregion

  #region Broker

  [XmlType("Broker")]
  public class Broker
  {
    [XmlAttribute]
    public bool Primary { get; set; }

    public long Id { get; set; }
  }

  #endregion
}

单元测试:

using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestApplication
{
  [TestClass]
  public class UserPreferencesTests
  {
    [TestMethod]
    public void DeserializeExistingUserXml()
    {
      string filename = "user.xml";
      if (!File.Exists(filename))
      {
        throw new FileNotFoundException("Could not find file " + filename);
      }

      string xmlPreferences = File.ReadAllText(filename);
      DateTime startTime = DateTime.Now;
      UserPreferences preferences = UserPreferences.DeserializeFrom(xmlPreferences);
      TimeSpan duration = DateTime.Now.Subtract(startTime);

      Assert.IsTrue(duration.Milliseconds < 100, "The deseralization time took longer than 100ms: " + duration.Milliseconds + "ms");

      // Tests

      Assert.IsNotNull(preferences);
      Assert.AreEqual(2, preferences.FavoriteQuotePages.Count);

      var pageGroup = preferences.FavoriteQuotePages[0];
      Assert.AreEqual(2, pageGroup.Pages.Count);
      Assert.AreEqual("Default", pageGroup.Name);
      var page = pageGroup.Pages[0];
      Assert.AreEqual("NG Options", page.Name);
      page = pageGroup.Pages[1];
      Assert.AreEqual("NG Options", page.Name);

      pageGroup = preferences.FavoriteQuotePages[1];
      Assert.AreEqual(2, pageGroup.Pages.Count);
      Assert.AreEqual("CUSTOM PAGES", pageGroup.Name);

      Assert.AreEqual(1, preferences.LayoutSettings.Count);
      Assert.AreEqual(1, preferences.QuoteDefaults.ClearingEntityIds.Count);
      Assert.AreEqual(6, preferences.QuoteDefaults.DeskBrokers.Count);
    }
  }
}

2 个答案:

答案 0 :(得分:0)

只需更改

[XmlArray("Group")]
public List<Page> Pages { get; set; }

[XmlElement("PageName")]
public List<Page> Pages { get; set; }

享受;)

注意:您的XML使用“today”作为startdate - 这与DateTime无关。

答案 1 :(得分:0)

您只需将PagweGroup页面更改为:

[XmlType("Group")]
public class PageGroup
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("PageName")]
    public List<Page> Pages { get; set; }

    public PageGroup()
    {
        Pages = new List<Page>();
    }
}

而不是XmlArray(“Group”),你必须把XmlElement(“PageName”)

请注意,之后,您的XML在startDate&amp;中的“today”字符串上有错误。 endDate属性