c # XML десериализация - PullRequest
       5

c # XML десериализация

0 голосов
/ 20 ноября 2018

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

Я создал собственную коллекцию объектов.

 public class ObjectCollection<T> : IEnumerable<T>, IEnumerable where T : IUniqueObjectIdentifier
{

    protected List<T> List = new List<T>();
    protected Dictionary<Guid, int> Keys = new Dictionary<Guid, int>();
    protected Dictionary<int, Guid> Inverse = new Dictionary<int, Guid>();
    protected Dictionary<string, Guid> Name = new Dictionary<string, Guid>();
    public void Add(T item)
    {
        if (item is IUniqueObjectIdentifier itemIdentifier)
            if (!Keys.ContainsKey(itemIdentifier.Id))
            {
                List.Add(item);
                Keys.Add(itemIdentifier.Id, List.IndexOf(item));
                Inverse.Add(List.IndexOf(item), itemIdentifier.Id);
            }
    }
    public void Remove(T item)
    {
        if (item is IUniqueObjectIdentifier itemIdentifier)
            if (List.Contains(item))
            {
                int index = List.IndexOf(item);
                Guid key = Inverse[index];
                Keys.Remove(itemIdentifier.Id);
                Inverse.Remove(index);
                List.Remove(item);
            }
    }
    public void Remove(int index)
    {
        if (index < List.Count)
        {
            Guid key = Inverse[index];
            Keys.Remove(key);
            List.RemoveAt(index);
            Inverse.Remove(index);
        }
    }

    public void Remove(Guid key)
    {
        if (Keys.ContainsKey(key))
        {
            int index = Keys[key];
            Keys.Remove(key);
            List.RemoveAt(index);
            Inverse.Remove(index);
        }
    }

    public void Clear()
    {
        Keys.Clear();
        List.Clear();
        Inverse.Clear();
    }

    public int Count => List.Count;

    public bool Contains(T item)
    {
        return List.Contains(item);
    }

    public bool ContainsKey(Guid key)
    {
        return Keys.ContainsKey(key);
    }

    public T this[int index]
    {
        get
        {
            if (index < List.Count)
                return List[index];
            else
                return default(T);
        }
    }

    public T this[Guid key]
    {
        get
        {
            if (Keys.ContainsKey(key))
                return List[Keys[key]];
            else
                return default(T);
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return List.GetEnumerator();
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    { return List.GetEnumerator(); }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return List.GetEnumerator();
    }

У меня есть Thing:

public class Thing
{
    //Collections
    [XmlElement(ElementName = "Fields")]
    public Fields Fields { get; set; }

Объект Fields наследуется от ObjectCollection:

[XmlRoot(ElementName = "Field")]
public class Fields:ObjectCollection<Field>
{

}

Наконец, у меня есть класс поля, который содержитвесь набор свойств:

[XmlRoot(ElementName = "Field")]
public class Field : IUniqueObjectIdentifier
{
    [XmlElement(ElementName = "FLAGS")]
    public int Flags{ get; set; }

ЕДИНСТВЕННЫЙ способ, которым это, кажется, работает, если я создаю свой класс полей, как это:

[XmlRoot(ElementName = "Fields")]
public class Fields
{
    [XmlElement(ElementName = "Field")] private List<Field> Items { get; set; }
}

Который я ненавижу.Необходим доступ к нему, например, Thing.Fields.Items.Add, а не Thing.Fields.Add.не имеет смысла для меня.

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

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </Field>
    <Field ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

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

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

Может кто-нибудь помочь направить меня в правильном направлении.Я просто хочу аккуратное и опрятное решение - с наименьшим количеством сложности !!!Как и все мы :-)

Любая помощь будет высоко ценится, прежде чем я прыгну с местного пирса.

Приветствия,

Stu.

1 Ответ

0 голосов
/ 21 ноября 2018

Хорошо, я немного упростил пример в своем посте с:

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <AField ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </AField>
    <AField ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

до:

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </Field>
    <Field ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

И:

[XmlRoot(ElementName = "AField")]
public class Fields:ObjectCollection<Field>
{

}

До:

[XmlRoot(ElementName = "Field")]
public class Fields:ObjectCollection<Field>
{

}

Ответ заключается в том, что ДАЖЕ, ЧТОБЫ вы указали корень, он не будет автоматически корректно отображаться на объект;ВАМ НУЖНО УКАЗАТЬ ЕГО [XmlType ("AField")], очевидно, если они не совпадают.В опубликованном случае: XmlRoot(ElementName = "Field")] = <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">

Так что это работает:

[XmlRoot(ElementName = "AField")]
[XmlType("AField")]
public class Fields:ObjectCollection<Field>
{

}

Извлеченные уроки:

  1. Не просто ваши примеры;отправьте их КАК ЕСТЬ!
  2. Если у вас есть проблема, разбейте ее на малейшие действия, чтобы преодолеть ее.

Я не могу не чувствовать, что это немного задом напередтот факт, что вы сопоставили его с корневым элементом, но эй.Благодаря dbc в их помощи с этим, или я чувствую, что был бы на дне моря.Проголосовал за огромное усилие.

Фу!

Stu.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...