Если бы мы создали схему для вашего <B>
узла, она бы состояла из последовательности из выбора узлов, где элемент типа <C>
, <D>
или <B>
само по себе может быть выбрано.
Если бы мы смоделировали это в c #, естественным способом было бы использовать список полиморфных объектов, элементы которых соответствовали бытри типа элементов. К счастью, как объяснено в этом ответе на Использование XmlSerializer для сериализации производных классов от Марк Гравелл , этот сценарий поддерживается XmlSerializer
аннотируя полиморфную коллекцию атрибутами [XmlElement(String, Type)]
, по одному для каждого конкретного типа, который может появиться в коллекции.
Таким образом, вы можете определить свою модель данных следующим образом:
public class BaseNode
{
}
public class B : BaseNode
{
[XmlElement("B", typeof(B))]
[XmlElement("C", typeof(C))]
[XmlElement("D", typeof(D))]
public List<BaseNode> Nodes { get; } = new List<BaseNode>();
}
public class C : BaseNode
{
[XmlElement(ElementName="E")]
public List<string> E { get; set; }
[XmlElement(ElementName="F")]
public List<bool> F { get; set; }
[XmlElement(ElementName="G")]
public G1 G { get; set; }
}
public class D : BaseNode
{
[XmlElement(ElementName="E")]
public string E { get; set; }
[XmlElement(ElementName="G")]
public G2 G { get; set; }
}
public class G1
{
public string H { get; set; }
}
public class G2
{
public string F { get; set; }
public string E { get; set; }
}
[XmlRoot("A")]
public class A
{
public B B { get; set; }
}
Примечания:
Я сделал 3 типа, которые могут появиться в коллекции B.Nodes
, наследовать от общего предка BaseNode
, так что добавить его невозможноне относящиеся к делу предметы в коллекцию во время выполнения. Если вы не хотите этого, вы можете исключить BaseNode
и объявить свою коллекцию как List<object>
.
По моему опыту, различные инструменты, упомянутые в Генерация класса C # из XML не всегда генерирует оптимальные классы c # из XML, который имеет сложные <xsd:choice>
+ <xsd:sequence>
сценарии.
Однако, если у вас был правильный XSD, инструменты из Как генерировать классы .NET 4.0 из xsd? сгенерировали бы правильные классы c #.
В вашем примере у вас есть два узла с именем <G>
, которые, кажется, имеют разные схемы, поэтому мне пришлось создать два типа G1
и G2
.
Демонстрационная скрипка здесь .