Десериализация трудно сформированного объекта XML в C # - PullRequest
2 голосов
/ 28 января 2010

У меня есть XML, который возвращается сторонним веб-сервисом в следующей форме:

<object>
    <list name="subscriptions">
        <object>
            <string name="id">something</string> 
            <string name="title">something else</string> 
            <list name="categories" /> 
            <number name="timestamp">1252707770116</number> 
        </object>
        ...more 'object'...
    </list>
</object>

У меня много проблем при попытке десериализации этих данных в объект. Я не смог сгенерировать схему с использованием xsd.exe, поэтому я вручную создал следующие классы, чтобы попытаться уместить эти данные:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlAttribute()]
    public string id;
    [XmlAttribute()]
    public string title;
    [XmlAttribute()]
    public string[] categories;
    [XmlAttribute()]
    public string timestamp;
}

Я пытаюсь десериализовать это с помощью следующего кода:

XmlSerializer s = new XmlSerializer(typeof(ListOfSubscriptions));
StreamReader r = new StreamReader("out.xml");
ListOfSubscriptions listSubscribe = (ListOfSubscriptions)s.Deserialize(r);
r.Close();

Однако, когда он заканчивается, listSubscribe имеет одного члена, и все его поля равны нулю.

Как мне создать шаблон для десериализации?

Спасибо

Обновление - 2010/01/28

Благодаря всем комментариям я изменил свои классы следующим образом:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public SubscriptionList[] items;
}
[XmlRoot("list")]
public class SubscriptionList
{
    [XmlElement("object")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlElement("string")]
    public string id;
    [XmlElement("string")]
    public string title;
    [XmlElement("list")]
    public string[] categories;
    [XmlElement("number")]
    public string timestamp;
}

Если я закомментирую строки [XmlElement (...)] в подписке и запустлю, я получу, что listSubscribe имеет один элемент SubscriptionList, который имеет правильное количество подписок, однако все элементы подписки нулевые.

Если я раскомментирую строки XmlElement, я получаю сообщение об ошибке, отражающее подписку. Я предполагаю, что это запутывается, потому что есть несколько элементов с одинаковым именем.

Как связать имя атрибута с членом класса?

Ответы [ 4 ]

4 голосов
/ 28 января 2010

Вы на правильном пути. Однако вы определяете только два класса. На самом деле нужно определить три класса:

  1. Единственный корневой объект с XML-именем «объект». Это будет иметь только один член:
  2. Список объектов (с XML-именем «list»). Это будет один член, массив:
  3. Подписки с XML-именем "объекта".

Другая проблема заключается в том, что вы определяете поля подписки как атрибуты. Это не атрибуты, это элементы.

2 голосов
/ 29 января 2010

Вы никогда не получите ничего с XML, как это:

<string name="id">something</string>  

Это просто создано кем-то, кто не знает XML. Эквивалент:

<id>something</id>

будет легко десериализовать.


Единственный способ десериализации, который я могу придумать, заключается в реализации интерфейса IXmlSerializable в вашем классе (ах).

0 голосов
/ 29 января 2010

Я полагаю, что вы можете использовать утилиту фреймворка XSD.exe .Net для создания класса, который может использоваться в виде представления вашего документа в памяти.

0 голосов
/ 28 января 2010

Вы хотите изменить XmlArry и XMLArrayItem .

Здесь является примером. Это должно выглядеть примерно так:

[XmlArray("FullNames")]
[XmlArrayItem("Name")]
public string[] Names{get;set;}

даст вам

<FullNames>
    <Name>Michael Jackson</Name>
    <Name>Paris Hilton</Name>
</FullNames>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...