2017-06-26 2 views
-1

Ich habe ein vorhandenes XML-Dokument, das ich einer C# -Klasse zuordnen möchte.Wie deserialize innere XML zu einem Objekt?

Ich habe auch einen Komponententest erstellt, um sicherzustellen, dass die XML-Eigenschaft deserialisiert wird.

Der Komponententest schlägt jedoch fehl, wenn für PageName-Elemente eine Anzahl von 2 erwartet wird. Wenn ich debugge, sehe ich, dass die Anzahl der PageName-Elemente 0 ist. Auch in der Debug-Ansicht haben die einzelnen DeskBroker.Broker-Elemente ebenfalls 0.

Nicht sicher, ob ich die XML-Attribute richtig einstelle. Kann jemand bitte meine Arbeit überprüfen und sehen, ob ich die richtigen Anmerkungen verwende? Ich bin mir sicher, dass ich etwas vermisse.

Vielen Dank.

Dies ist der 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> 

ich die XML definiert sich wie folgt:

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 
} 

Die Tests Einheit:

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); 
    } 
    } 
} 
+3

Wenn unten eine Frage abstimmen, können Sie bitte einen Grund für die Abstimmung unten geben? Lasst uns hier etwas Transparenz haben. –

+0

Mit Blick auf diese Frage, kann eine Lösung für mich haben: https://stackoverflow.com/questions/364253/how-to-deserialize-xml-document?rq=1 –

Antwort

0

einfach

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

zu

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

Genießen;)

Hinweis: Ihr XML verwendet "heute" als Startdatum - die nicht mit Datetime funktioniert.

+0

Danke Simon. Ich habe die Änderung an XMLElement ("PageName") vorgenommen und die Felder "startdate" und "enddate" so geändert, dass sie jetzt Strings sind. Das PageName-Element und die Unterelemente in XML werden jedoch immer noch nicht analysiert. Wie würde ich das Feld definieren, das den internen Text von PageName enthält? –

+0

Das Problem hier ist, dass [XmlElement ("PageName")] nicht dasselbe ist wie die Deklaration [XmlType ("PageName")] auf der Klassenseite selbst - eine ist die Sammlung, die andere das einzelne Element - ändern [XmlType ("PageName")] zu [XmlType ("PageNameElement")] und die Elemente werden aufgefüllt. Um die öffentliche Zeichenkette Name {get; einstellen; } um zu arbeiten müssen Sie das [XmlElement] zu [XmlText] ändern, da es kein Element ist, sondern der eigentliche Inhalt;) –

0

Sie müssen lediglich Ihre PagweGroup Seite dies ändern:

[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>(); 
    } 
} 

Statt XmlArray ("Gruppe"), müssen Sie XmlElement setzen ("Seitenname")

Beachten Sie, dass nach, dass Ihre XML hat Fehler in der Zeichenfolge "heute" in Startdatum & endDate Attribute

+0

Danke Eric. Ich habe die Änderung vorgenommen, so dass das Feld Seiten jetzt Seitenobjekte enthält, die jedoch nicht die Werte aus dem Dokument enthalten. –

Verwandte Themen