Десериализация нескольких XML элементов в одном объекте - PullRequest
1 голос
/ 14 апреля 2020

Я использую XmlSeriazlier для десериализации файла xml.

var serializer = new XmlSerializer(typeof(T));
using (var reader = document.CreateReader())
   var result = (T)serializer.Deserialize(reader);

Xml содержит условия if / else if / else, которые необходимо хранить вместе в одном объекте.

Пример Xml

<Layers>
  <If if="something" >
    <Layer name="something" />
  </If>
  <ElseIf if="anything" >
    <Layer name="anything" />
  </ElseIf>
  <Else>
    <Layer name="nothing" />
  </Else>

  <If if="something" >
    <Layer name="something" />
  </If>
  <ElseIf if="anything" >
    <Layer name="anything" />
  </ElseIf>

  <If if="something" >
    <Layer name="something" />
  </If>
  <Else>
    <Layer name="nothing" />
  </Else>
</Layers>

Синтаксис аналогичен языку программирования. Мне интересно, как я могу хранить связанные условия вместе.

[XmlRoot("Layers")
public class Layers
{
    // TODO: Parse conditions to this list.
    public List<Condition> { get; set; }
}

public class Condition
{
    public If IfCondition { get; set; }
    public List<IfElse> IfElseConditions { get; set; }
    public Else ElseCondition { get; set; }
}

1 Ответ

0 голосов
/ 14 апреля 2020

Есть некоторые существенные проблемы с этим выбором xml схемы, которые делают его не очень хорошим выбором для XmlSerializer. В частности, нет никакого условного <Condition> (или подобного), что означает, что с точки зрения сериализатора нет ничего, что группирует эти условия. Чтобы захватить данные , вам потребуется:

[XmlRoot("Layers")
public class Layers
{
    [XmlElement("If")]
    public List<If> { get; set; } // you may be able to share the inner type here
    [XmlElement("ElseIf")]
    public List<ElseIf> { get; set; }
    [XmlElement("Else")]
    public List<Else> { get; set; }
}

, но теперь вы не знаете, какие элементы if go с какими элементами else-if и go с какими другими elements.

Я подозреваю, что вам придется реализовать это вручную, добавив свой собственный лог c при переключении между типами узлов, но это не тривиально. Честно говоря, возможно, было бы проще пересмотреть макет xml, если это возможно! Например:

<Layers>
  <Condition><!-- some kind of "first match wins" grouping -->
    <Match if="something">
        <Layer name="something" />
    </Match>
    <Match if="anything"><!-- note no need for different if/elseif -->
        <Layer name="anything" />
    </Match>
    <Match> <!-- no "if": acts as wildcard, i.e. "else" -->
        <Layer name="nothing" />
    </Match>
  </Condition>
  <!-- etc -->
</Layers>
...