Как десериализовать список объектов, где дети находятся прямо в корне - PullRequest
4 голосов
/ 20 февраля 2012

Рассмотрим следующий XML:

<?xml version="1.0" encoding="utf-8"?>
<treelist id="foo" displayname="display">
  <treelink id="link" />
</treelist>

У меня настроен следующий код:

    private static void Main(string[] args)
    {
        StreamReader result = File.OpenText(@"test.xml");

        var xmlTextReader = new XmlTextReader(result.BaseStream, XmlNodeType.Document, null);

        XDocument load = XDocument.Load(xmlTextReader);

        var xmlSerializer = new XmlSerializer(typeof (TreeList));

        var foo = (TreeList) xmlSerializer.Deserialize(load.CreateReader());
    }

А это мои сущности:

[Serializable]
[XmlRoot("treelink")]
public class TreeLink
{
    [XmlAttribute("id")]
    public string Id { get; set; }
}

[Serializable]
[XmlRoot("treelist")]
public class TreeList
{
    [XmlAttribute("id")]
    public string Id { get; set; }

    [XmlAttribute("displayname")]
    public string DisplayName { get; set; }

    [XmlArray("treelist")]
    [XmlArrayItem("treelist", typeof (TreeLink))]
    public TreeLink[] TreeLinks { get; set; }
}

Однако я не могу десериализовать объекты Treelink, в foo TreeLinks всегда остается нулевым.

Что я здесь не так делаю?

Спасибо

1 Ответ

7 голосов
/ 20 февраля 2012

Используйте XmlElement в «списке» древовидных ссылок.

[XmlElement("treelink")]
public TreeLink[] TreeLinks { get; set; }

Использование [XmlArray] и [XmlArrayItem] подразумевает, что вы хотите, чтобы ссылки на дерево находились в их собственном контейнере-обертке в родительском классе - другими словами, он ожидает xml, подобный этому:

<treelist id="foo" displayname="display">
  <treelist>
    <treelist id="link" />
  </treelist>
</treelist>

Хитрость в том, чтобы всегда начинать в другом направлении. Разметьте ваш класс для сериализации, а затем сериализуйте экземпляр вашего типа и посмотрите на xml, который он генерирует. Затем вы можете настроить его так, чтобы он выглядел как XML, который вы в конечном итоге хотите десериализовать. Это гораздо проще, чем пытаться угадать, почему ваш xml не десериализован правильно.

...