Поддержка привязки атрибута 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>

Возможные значения:

  • 1: программа Xsd.exe создает поле, тип которого соответствует типу данных элемента.

  • 0: программа Xsd.exe не обрабатывает значение 0, рассматривая его как значение по умолчанию 1.

  • unbounded: программа Xsd.exe создает поле, представляющее собой массив типа, соответствующего типу данных элемента.

  • Любое целое число, превышающее 1: как и в случае значения unbounded, программа Xsd.exe создает поле, представляющее собой массив типа, соответствующего типу данных элемента. Можно принудительно задать значение больше 1, проверив документ XML при помощи класса XmlValidatingReader на соответствие документу схемы XML, представленному моделью SOM.

<group>

Для элемента <group> значение 0 атрибута maxOccurs интерпретируется программой Xsd.exe как значение 1, а значение атрибута maxOccurs, превосходящее 1, интерпретируется как unbounded.

Однако по умолчанию программа Xsd.exe рассматривает значение maxOccurs="unbounded" для элемента <group> так, как если бы значение maxOccurs="unbounded" было указано для каждого из дочерних элементов. Например, если каждый дочерний элемент элемента <group> является элементом <element>, то каждое поле, создаваемое в результирующем классе, является массивом соответствующего типа.

Для правильного импорта схем, содержащих группы со значением maxOccurs больше 1, рекомендуется использовать в программе Xsd.exe параметр командной строки /order. Когда используется этот параметр, вся группа импортируется в виде одного массива с применением нескольких атрибутов XmlElementAttribute, по одному на каждый элемент группы. Тип массива определяется типами элементов — будет использоваться ближайший производный тип, к которому могут быть отнесены все элементы. То есть, если группа содержит элементы типов Type1 и Type2, оба из которых наследуются от типа TypeBase, массив будет иметь тип TypeBase. При отсутствии общего базового типа массив будет иметь тип Object. Соответствующий пример см. в примере <sequence> в конце этого раздела.

<all>

Любое значение атрибута maxOccurs, отличное от 1, является недопустимым. Программа Xsd.exe сообщает об ошибке из-за недопустимого значения.

<any>

Возможные значения:

  • 1: программа Xsd.exe создает поле типа System.Xml.XmlElement с атрибутом System.Xml.Serialization.XmlAnyElementAttribute. Этот атрибут позволяет классу представлять произвольные элементы XML, не привязывая их к идентифицированным другими возможными членами класса типам, не являющимся типами XML.

  • 0: программа Xsd.exe не обрабатывает значение 0, рассматривая его как значение по умолчанию 1.

  • unbounded: программа Xsd.exe создает массив XmlElement с атрибутом XmlAnyElement.

  • Любое целое число, большее 1: как и в случае значения unbounded, программа Xsd.exe создает массив XmlElement с атрибутом XmlAnyElement. Можно принудительно задать значение больше 1, проверив документ XML при помощи класса XmlValidatingReader на соответствие документу схемы XML, представленному моделью SOM.

<choice>

Элемент <choice> содержит не менее двух дочерних элементов, каждый из которых представляет элемент или группу элементов. Он указывает, что, в определенном документе экземпляра, в указанной позиции может появляться только одна из этих сущностей. Варианты должны различаться по имени элемента; дополнительно они могут различаться по типу и, в случае группы, по номеру. Дополнительные сведения см. в описании элемента <choice>.

Для элемента <choice>, как и для элементов <element> и <any>, значение 0 атрибута maxOccurs интерпретируется программой Xsd.exe как значение 1, а значение атрибута maxOccurs, превосходящее 1, интерпретируется как unbounded.

Для значения 1 программа Xsd.exe создает поле общего типа или общего базового типа. Для каждого варианта к этому полю применяется атрибут типа XmlElementAttribute. Если варианты не отличаются по типу, программа Xsd.exe создает атрибут типа XmlChoiceIdentifierAttribute, задающий второе поле типа перечисления, которое представляет каждый из вариантов. Подробно этот механизм рассматривается (вместе с примерами) в описании элемента <choice>.

Для значения unbounded программа Xsd.exe выполняет такую же привязку, но поле, создаваемое для варианта, представляет собой массив соответствующего типа. Если все варианты имеют одинаковый тип, второе поле (идентифицируемое атрибутом XmlChoiceIdentifier) представляет собой массив созданного типа перечисления. Каждый элемент второго массива выбирает имя элемента для соответствующего элемента в первом массиве.

<sequence>

Для элемента <sequence>, как и для большинства предыдущих элементов, значение 0 атрибута maxOccurs интерпретируется программой Xsd.exe как значение 1, а значение атрибута maxOccurs, превосходящее 1, интерпретируется как unbounded.

Однако программа Xsd.exe рассматривает значение maxOccurs="unbounded" для элемента <sequence> так, как если бы каждый дочерний элемент был указан с атрибутом maxOccurs="unbounded". Например, если каждый дочерний элемент элемента <sequence> является элементом <element>, то каждое поле, создаваемое в результирующем классе, является массивом соответствующего типа. Программа Xsd.exe привязывает эту структуру полей к элементу <sequence maxOccurs="1">, содержащему заданное число элементов <element maxOccurs="unbounded">, если производится обратное преобразование в новый документ XSD.

Применяются атрибуты 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