Как анализировать узлы со смешанными повторяющимися и неповторяющимися дочерними узлами? - PullRequest
0 голосов
/ 19 февраля 2019

Давайте начнем с удаления любого понятия, что это может быть дубликатом Как читать XML-документ в ядре MVC (1.0.0)? , который рассматривает только эту структуру, тривиально выражаемую как things: thing[].

<things>
  <thing>..</thing>
  <thing>..</thing>
  <thing>..</thing>
  …
</things>

Этот вопрос о том, как выразить следующее как классы.

<things>
  <a>..</a>
  <b>..</b>
  <c>..</c>
  <d>..</d>
  <d>..</d>
  <d>..</d>
  …
</things>

Это абсолютно , а не массив.Это , возможно, словарь, но нам явно запрещено использовать IDictionary<T1,T2> с XmlSerializer.

Обычно я начинаю с классов и позволяю XmlSerializer сообщать мне формат XML, но этоXML определяется системой вне моего контроля.

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

Как десериализовать узел со смешанными повторяющимися и неповторяющимися дочерними узлами?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Как только вы найдете его, ответ будет очень прост: вы применяете атрибут XmlElement к члену массива.Более подробную информацию можно получить по адресу https://docs.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes#serializing-an-array-as-a-sequence-of-elements

public class thing {
  public string a { get; set; }
  public string b { get; set; }
  public string c { get; set; }
  [XmlElement]
  public string[] d { get; set; }
}

. Затем мы можем проанализировать ноль или более вхождений d как прямых потомков без узла сбора, чтобы владеть и напечатать их, в свойство массива нашего объекта thing.

Чтобы прояснить влияние атрибута, значение свойства thing.d представляет собой коллекцию , в которой элементы являются анонимными и имеют тип string.Сериализация точно отражает это, давая вам узел коллекции "d" с дочерними узлами, которые получают свои имена по типу:

<things>
  <a>..</a>
  <b>..</b>
  <c>..</c>
  <d>
    <string>..</string>
    <string>..</string>
    …
  </d>
</things>

Однако это не то, что мы пытаемся проанализировать.Атрибут [XmlElement] запрещает рассматривать свойство как коллекцию, и, если оно не является коллекцией, единственный другой способ сопоставления его с XML - это повторяющийся элемент.

0 голосов
/ 19 февраля 2019

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

[XmlInclude(typeof(A))]
[XmlInclude(typeof(B))]
...
public class BaseClass {}

[XmlRoot("a")]
public class A : BaseClass { }

[XmlRoot("b")]
public class B : BaseClass { }
...

public class Things
{
   [XmlElement("things")]
   public BaseClass[] Items { get; set; }
}
...