c # десериализация вложенных коллекций XML - PullRequest
2 голосов
/ 14 февраля 2012

Привет, у меня есть XML, который я хочу десериализовать в .NET POCO с помощью XMLSerializer

XML выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
  <message uuid="{2f1e274c-6a53-afea-3047-6dc739539656}">
    <envelope received="a_date" subject="a_name">
      <from>
        <monitor name="Local Folder" user_description="" uuid="{668DC658-97D7-42c8-AE72-ED289DD02355}"/>
      </from>
      <to>
        <account>
          <factory name="a_name"/>
        </account>
      </to>
    </envelope>
    <status>
      <action name="Folder" occured="a_date" type="monitor">
        <session completed="a_date" name="a_name" started="a_date"/>
      </action>
      <action occured="a_date" type="monitor"/>
      <action occured="a_date" type="translate">
        <session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="time"/>
        <session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="time"/>
      </action>
      <action occured="a_date" type="deliver">
        <session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="byte"/>
        <session completed="a_date" name="a_name" started="a_date" unit="byte"/>
        <session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="byte"/>
      </action>
      <action occured="a_date" type="complete"/>
    </status>
    <host name="a_name"/>
</message>

В XML есть раздел статуса, которыйсодержит набор действий, каждое действие может содержать набор сеансов.

Я создал классы для XMLSerialiser для десериализации xml:

namespace myNameSpace
{
    [XmlRoot("message")]
    public class message
    {
        [XmlAttribute("uuid")] 
        public string uuid { get; set; }
        [XmlElement("envelope")]
        public envelope envelope { get; set; }
        [XmlArray("status")]
        [XmlArrayItem(typeof(action))]
        public ObservableCollection<action> status { get; set; }
        [XmlElement("host")]
        public host host { get; set; }
    }

    public class envelope
    {
        [XmlAttribute("received")] 
        public string received { get; set; }
        [XmlAttribute("subject")]
        public string subject { get; set; }
        [XmlElement("from")]
        public from from { get; set; }
        [XmlElement("to")]
        public to to { get; set; }
    }

    #region envelope element definitions

    public class from
    {
        [XmlElement("monitor")]
        public monitor monitor { get; set; }

    }

    public class monitor
    {
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlAttribute("user_description")]
        public string user_description { get; set; }
        [XmlAttribute("uuid")]
        public string uuid { get; set; }

    }

    public class to
    {
        [XmlElementAttribute("account")]
        public account account { get; set; }
    }

    public class account
    {
        [XmlElementAttribute("factory")]
        public factory factory { get; set; }
    }

    public class factory
    {
        [XmlAttribute("name")]
        public string name { get; set; }
    }

    #endregion

    public class action
    {
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlAttribute("occured")]
        public string occured { get; set; }
        [XmlAttribute("type")]
        public string type { get; set; }
        [XmlArray("action")]
        [XmlArrayItem(typeof(session))]
        public ObservableCollection<session> session { get; set; }
    }

    public class session
    {
        [XmlAttribute("completed")]
        public string completed { get; set; }
        [XmlAttribute("current")]
        public long current { get; set; }
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlAttribute("started")]
        public string started { get; set; }
        [XmlAttribute("total")]
        public long total { get; set; }
        [XmlAttribute("unit")]
        public string unit { get; set; }
    }

    public class host
    {
        [XmlAttribute("name")]
        public string name { get; set; }
    }
}

В основном я получаю желаемый граф объектовсо всеми правильными десериализованными значениями, но я не могу найти способ заставить XMLSerialiser десериализовать коллекцию сеансов в элементе действия - они всегда пусты.

Кто-нибудь знает, как я мог бы построить свои POCO, чтобыXMLserialiser может создавать коллекции сеансов?

С наилучшими пожеланиями

Джон.

Ответы [ 3 ]

4 голосов
/ 14 февраля 2012

Это было сгенерировано с помощью xsd.exe.Надеюсь, это поможет.

using System.Xml.Serialization;
using System.Xml.Schema;
using System;

[SerializableAttribute()]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class message
{
    [XmlElementAttribute("envelope", Form = XmlSchemaForm.Unqualified)]
    public messageEnvelope[] envelope { get; set; }

    [XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
    [XmlArrayItemAttribute("action", typeof(messageStatusAction), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
    public messageStatusAction[][] status { get; set; }

    [XmlElementAttribute("host", Form = XmlSchemaForm.Unqualified)]
    public messageHost[] host { get; set; }

    [XmlAttributeAttribute()]
    public string uuid { get; set; }
}

[SerializableAttribute()]
public partial class messageEnvelope
{
    [XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
    [XmlArrayItemAttribute("monitor", typeof(messageEnvelopeFromMonitor), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
    public messageEnvelopeFromMonitor[][] from { get; set; }

    [XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
    [XmlArrayItemAttribute("account", typeof(messageEnvelopeTOAccountFactory[]), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
    [XmlArrayItemAttribute("factory", typeof(messageEnvelopeTOAccountFactory), Form = XmlSchemaForm.Unqualified, IsNullable = false, NestingLevel = 1)]
    public messageEnvelopeTOAccountFactory[][][] to { get; set; }

    [XmlAttributeAttribute()]
    public string received { get; set; }

    [XmlAttributeAttribute()]
    public string subject { get; set; }
}

[SerializableAttribute()]
public partial class messageEnvelopeFromMonitor
{
    [XmlAttributeAttribute()]
    public string name { get; set; }

    [XmlAttributeAttribute()]
    public string user_description { get; set; }

    [XmlAttributeAttribute()]
    public string uuid { get; set; }
}

[SerializableAttribute()]
public partial class messageEnvelopeTOAccountFactory
{
    [XmlAttributeAttribute()]
    public string name { get; set; }
}

[SerializableAttribute()]
public partial class messageStatusAction
{
    [XmlElementAttribute("session", Form = XmlSchemaForm.Unqualified)]
    public messageStatusActionSession[] session { get; set; }

    [XmlAttributeAttribute()]
    public string name { get; set; }

    [XmlAttributeAttribute()]
    public string occured { get; set; }

    [XmlAttributeAttribute()]
    public string type { get; set; }
}

[SerializableAttribute()]
public partial class messageStatusActionSession
{
    [XmlAttributeAttribute()]
    public string completed { get; set; }

    [XmlAttributeAttribute()]
    public string name { get; set; }

    [XmlAttributeAttribute()]
    public string started { get; set; }

    [XmlAttributeAttribute()]
    public string current { get; set; }

    [XmlAttributeAttribute()]
    public string total { get; set; }

    [XmlAttributeAttribute()]
    public string unit { get; set; }
}

[SerializableAttribute()]
public partial class messageHost
{
    [XmlAttributeAttribute()]
    public string name { get; set; }
}

[SerializableAttribute()]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{
    [XmlElementAttribute("message")]
    public message[] Items { get; set; }
}
0 голосов
/ 14 февраля 2012

Во-первых, session должен наследовать action.

Затем вам может потребоваться заменить public ObservableCollection<action> status { get; set; } на public List<action> status { get; set; } или public action[] status { get; set; } (я не делаю, если ObservableCollection считается XmlSerializable).

Наконец, вам, возможно, придется добавить [XmlInclude(typeof(session))] в объявление класса action.

0 голосов
/ 14 февраля 2012

Я считаю, что ваша проблема заключается в том, что когда вы находитесь на уровне действия, вы не можете указать его как тип XmlArray.Это были бы сессии.Попробуйте и посмотрите, работает ли он:

public class action
{
    [XmlAttribute("name")]
    public string name { get; set; }
    [XmlAttribute("occured")]
    public string occured { get; set; }
    [XmlAttribute("type")]
    public string type { get; set; }
    [XmlArray(typeof(session))]
    public ObservableCollection<session> session { get; set; }
}
...