Поддержка привязки атрибута MaxOccurs
Этот раздел посвящен технологии прежних версий. Веб-службы XML и клиенты веб-служб XML должны создаваться с использованием Windows Communication Foundation.
Платформа .NET Framework обеспечивает частичную поддержку привязки для атрибута maxOccurs.
Для большинства элементов, допускающих задание атрибута maxOccurs, программа Xsd.exe интерпретирует значение 0
как 1
, создавая поле, не являющееся массивом, а значение, большее 1, как unbounded
, создавая поле массива. Поведение для разных элементов различается.
Объяснение
Атрибуты maxOccurs и minOccurs ограничивают число последовательных появлений заданной сущности в соответствующей позиции в документе экземпляра XML.
Эти атрибуты появляются только в определениях сложных типов. Поэтому, чтобы элемент <element> или <group> мог иметь эти атрибуты, он должен быть локальным объявлением или ссылкой на глобальное объявление, но не глобальным объявлением.
Для привязки классов со сложными типами схемы XML платформа .NET Framework не предоставляет прямого языкового эквивалента атрибутов maxOccurs и minOccurs.
При создании исходного кода из документа схемы XML или при выполнении обратного преобразования программа Xsd.exe по-разному интерпретирует атрибут maxOccurs в зависимости от элемента языка определения схемы XML, в котором содержится этот атрибут. В следующей таблице приводятся пояснения по интерпретации для различных элементов.
Элемент | Интерпретация |
---|---|
<element> |
Возможные значения:
|
<group> |
Для элемента <group> значение Однако по умолчанию программа Xsd.exe рассматривает значение Для правильного импорта схем, содержащих группы со значением maxOccurs больше |
<all> |
Любое значение атрибута maxOccurs, отличное от |
<any> |
Возможные значения
|
<choice> |
Элемент <choice> содержит не менее двух дочерних элементов, каждый из которых представляет элемент или группу элементов. Он указывает, что, в определенном документе экземпляра, в указанной позиции может появляться только одна из этих сущностей. Варианты должны различаться по имени элемента; дополнительно они могут различаться по типу и, в случае группы, по номеру. Дополнительные сведения см. в описании элемента <choice>. Для элемента <choice>, как и для элементов <element> и <any>, значение Для значения Для значения |
<sequence> |
Для элемента <sequence>, как и для большинства предыдущих элементов, значение Однако программа Xsd.exe рассматривает значение Применяются атрибуты XmlElementAttribute, по одному для каждого элемента в группе. Тип массива определяется типами элементов — будет использоваться ближайший производный тип, к которому могут быть отнесены все элементы. То есть, если группа содержит элементы типов Type1 и Type2, оба из которых наследуются от типа TypeBase, массив будет иметь тип TypeBase. При отсутствии общего базового типа массив будет иметь тип Object. Соответствующий пример см. в примере <sequence> в конце этого раздела. |
При создании документа схемы XML из набора классов в сборке программа Xsd.exe обращает предыдущие преобразования, создавая атрибут maxOccurs со значением 1
из одного экземпляра и атрибут maxOccurs со значением unbounded
из массива.
Хотя программа Xsd.exe привязывает значение unbounded
атрибута maxOccurs к массиву, она привязывает значение 1
атрибута maxOccurs к назначенному родительскому элементу (при его наличии) массива.
Для представления родительского элемента массива создается тип данных схемы с именем, начинающимся с ArrayOf, если к массиву применен атрибут System.Xml.Serialization.XmlArrayAttribute по умолчанию. Если вместо этого к массиву применен атрибут System.Xml.Serialization.XmlElementAttribute, элементы массива включаются в документ экземпляра в виде дочернего элемента, привязанного к классу. Дополнительные сведения о привязках массива см. в разделе Управление XML-сериализацией с использованием атрибутов.
Дополнительные сведения о привязке массива. Чтобы понять преобразование значения, большего 1, в массив, обратите внимание на разницу между объявлением объекта определенного типа и присваиванием значения (буквально, ячейки памяти стека или кучи) этому объекту. Рассмотрим следующий элемент XSD:
<xsd:element minOccurs="5" maxOccurs="5" name="items" type="xsd:token" />
При написании кода вручную вы не станете выражать размер массива (5) в объявлении типа, которое будет таким: public string[] items
. Вместо этого вы укажете размер массива при присваивании значения: items = new string[5]
.
Xsd.exe генерирует из схемы XML только исходный код объявлений типов и полей, плюс метаданные, которые могут применяться к типам и полям как атрибуты. Присваивание значений объектам выходит за рамки области действия.
Способ принудительно задать значение больше 1 — проверить документ XML при помощи класса XmlValidatingReader на соответствие документу схемы XML, представленному объектной моделью схемы (SOM). Объектная модель схемы использует свойства System.Xml.Schema.XmlSchemaParticle.MaxOccurs и System.Xml.Schema.XmlSchemaParticle.MaxOccursString, оба они применяются ко всем элементам, которые могут содержать атрибут maxOccurs.
Example
Элемент <choice> входной схемы XML в определении сложного типа:
<xsd:choice maxOccurs="unbounded">
<xsd:element name="stringA" type="xsd:string"/>
<xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>
Соответствующие части кода класса C#, созданные из предыдущего документа схемы XML, и перечисление, представляющее варианты выбора элемента (предполагая целевое пространство имен http://example.org/):
[System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public string[] Items;
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType[] ItemsElementName;
...
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum ItemsChoiceType {
stringA,
stringB,
}
Сложный тип, созданный из класса, скомпилированного из приведенного выше исходного кода C#, фактически эквивалентен исходному сложному типу.
<sequence>
Example
Входной документ схемы XML, содержащий последовательность со значением атрибута maxOccurs, превосходящим 1
:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://example.org/" targetNamespace="http://example.org/" elementFormDefault="qualified">
<xsd:element name="ComplexInstance">
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="Field1" type="xsd:token"/>
<xsd:element name="Field2" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Класс C#, созданный на основе приведенного выше документа схемы XML без каких-либо параметров командной строки:
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.org/", IsNullable=false)]
public class ComplexInstance {
[System.Xml.Serialization.XmlElementAttribute("Field1", DataType="token")]
public string[] Field1;
[System.Xml.Serialization.XmlElementAttribute("Field2")]
public int[] Field2;
}
Сложный тип схемы XML, созданный из сборки, скомпилированной на основе предыдущего исходного кода C#:
<xs:complexType name="ComplexInstance">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Field1" type="xs:token" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="Field2" type="xs:int" />
</xs:sequence>
</xs:complexType>
Видно, что конечная схема не эквивалентна исходной схеме. Чтобы правильно импортировать схему, содержащую последовательности со значением атрибута maxOccurs, превышающим 1
, используйте параметр командной строки /order, дающий следующий результат:
[System.Xml.Serialization.XmlTypeAttribute
(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute
(Namespace="http://example.org/", IsNullable=false)]
public partial class ComplexInstance
{
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute
("Field1", typeof(string), DataType="token", Order=0)]
[System.Xml.Serialization.XmlElementAttribute("Field2",
typeof(int), Order=0)]
public object[] Items;
}
Возможные содержащие элементы: <all>, <any>, <choice>, <element>, <group>, <sequence>
См. также
Справочник
System.Xml.Schema.XmlSchemaParticle.MaxOccurs
System.Xml.Schema.XmlSchemaParticle.MaxOccursString
XmlSchemaAll
XmlSchemaAny
XmlSchemaChoice
XmlSchemaElement
XmlSchemaGroupRef
XmlSchemaSequence