Я использую XML в качестве формата конфигурации для приложения C #, над которым я сейчас работаю. Чтобы не заботиться о XSD и XML вручную, когда я изменяю что-то маленькое, я решил создать серию сериализованных классов, чтобы выполнить всю обработку за меня. Теперь я пытаюсь переместить все из схемы в мой код на C #, поскольку инструмент xsd
, предоставляемый .NET, похоже, игнорирует некоторые вещи (например, определения уникальных значений).
В XSD определен следующий тип xs:complexType
:
<xs:complexType name="ServiceType">
<xs:attribute name="uri" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Service1" />
<xs:enumeration value="Service2" />
<xs:enumeration value="Service3" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
Тип затем используется в следующих xs:element
:
<xs:element name="Services">
<xs:complexType>
<xs:sequence>
<xs:element name="Service" type="ServiceType"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="unique-serviceUri">
<xs:selector xpath="Service" />
<xs:field xpath="@uri" />
</xs:unique>
</xs:element>
Как видите, атрибут uri
, полученный из ServiceType
, определяется как уникальный. Перечисление предназначено для ограничения возможных значений, а уникальность позволяет гарантировать, что значение не встречается более одного раза.
Я только что узнал, что Enum
довольно легко сериализовать в C #:
[Serializable]
public class Service
{
public Service()
{
this.uri = ServiceUri.Invalid;
}
public enum ServiceUri
{
Service1,
Service2,
Service3,
[NonSerialized]
Invalid
};
[XmlAttribute("uri")]
public ServiceUri uri { get; set; }
}
Теперь проблема в том, что я не только хочу ограничить значения, но и делаю невозможным использование, например, Service1
более одного раза, как в моей исходной схеме.
У меня очень мало опыта, когда дело доходит до сериализации. Это похоже на ситуацию Dictionary
, но я не знаю, как включить ее в C #, чтобы в результате сериализации появился фрагмент XSD, который я выложил в начале. Это произошло бы в классе, который фактически содержит список Service
элементов:
[Serializable]
[XmlRoot("ProtocolConfiguration")]
public class ProtocolConfig
{
// ...
[XmlArray("Services")]
[XmlArrayItem("Service")]
public List<Service> Services { get; set; }
// ...
}