2012-02-14 3 views
2

Привет У меня есть некоторые XML я желаю deserialise для .NET Pocos с помощью XMLSerializerC# Deserialize XML Вложенные коллекции

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; } 
    } 
} 

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

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

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

John.

+0

опечатка? (или новый тип данных): 'public from from {get; задавать; } ' - должно быть, это строка? –

+0

no У меня есть класс под названием 'from': вы можете увидеть его в области определения элементов оболочки. – John

+0

Не было бы проще генерировать классы из xml с помощью xsd.exe? Из команды вы можете сделать: 1) xsd c: \ test.xml (это генерирует test.xsd), 2) xsd test.xsd/classes (генерирует test.cs) –

ответ

4

Это было сгенерировано с использованием 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

Спасибо Alex: Я только что сделал, как вы предложили, я посмотрел на код, сгенерированный инструментом, в частности атрибут, который он размещает в коллекции сеанса - [System.Xml.Serialization.XmlElementAttribute («session», Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] Я применил этот атрибут к моя коллекция сеансов в классе действий, и теперь xml полностью десериализуется. спасибо. Я никогда не был знаком с xsd comman перед тем, как его оценили. John – John

+0

Рад, что я мог помочь. –

0

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

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; } 
} 
+0

К сожалению, компилятор vs не нравится [XmlArray (typof (session))], он настаивает на том, что он должен быть строкой и дает следующую ошибку: System.Xml.Serialization.XmlArrayAttribute.XmlArrayAttribute (string) 'имеет некоторые недопустимые аргументы – John

+0

I согласитесь, что проблема в том, что я не могу определить массив «action» в классе действия. Если бы я имел контроль над xml, я бы вложил сессии в элемент session_collection. К сожалению, я должен взять xml как есть. – John

+0

@John - Ах, хорошо, использует ли строка («сессия») вместо использования typeof (угадывание не)? – SwDevMan81

0

Во-первых, 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

Наблюдается, что функция ObservableCollection работает: по мере того, как коллекция состояний сообщения десериализируется правильно. – John

+0

Привет, спасибо за быстрый ответ ... Наблюдается, что ObservableCollection работает: поскольку коллекция состояний сообщения десериализована правильно. Если я выполняю действие наследования сеанса ...когда я запускаю приложение, я получаю InvalidOperationException И добавление [XmlInclude (typeof (session))] не улучшает ситуацию, я все равно получаю пустые коллекции сеансов – John