Мы можем контролировать то, как элементы должны использоваться в документах с индикаторами.
В статье рассматриваются три способа представления нулевых полей в схеме XMLи показывается, в каких случаях лучше использовать тот или другой способ.
Компонентная объектная модель для Java, известная как Java beans, имеет
определенные свойства, называемые полями. Эти поля могут иметь нулевые
значения, если только они не являются полями примитивного типа. При
преобразовании («мэппировании») Java beans в XML эти поля становятся элементами
или атрибутами. Простые элементы и атрибуты не могут иметь нулевых значений (их
можно рассматривать как своего рода эквиваленты примитивным типам Java, которые
также не могут иметь нулевых значений). Существует несколько способов изменить
атрибуты и элементы XML таким образом, чтобы их экземпляры имели нулевое
значение (или хотя бы логически были эквивалентны нулю):
- для элементов:
использовать атрибут nillable=»true»;или использовать атрибут minOccurs=»0″. - или использовать атрибут minOccurs=»0″.
В предлагаемой статье обсуждаются детали и варианты каждого из этих
способов.
Элементы и атрибуты
Прежде чем рассматривать представления нулевых значений, необходимо решить,
что будет использоваться для поля объекта, — элемент или атрибут. В первую
очередь нужно определить тип этого поля. В атрибутах могут использоваться
только простые типы. Таким образом, при наличии сложного типа выбор однозначен
— должен использоваться элемент. Но в случае простого типа вопрос остается: что
лучше — атрибут или элемент? Например, при наличии структуры, приведенной в
листинге 1, что окажется лучше: attrField или elemField?
Листинг 1. Схема AttributeOrElement
В листинге 2 представлен экземпляр схемы листинга 1.
Листинг 2. Экземпляр AttributeOrElement
Ясно видно, что поле атрибута занимает меньше места в экземпляре, чем поле
элемента. Соответственно, сообщения SOAP, которые переносят документы в формате
XML, содержащие атрибуты, также будут меньше, что сократит время их передачи.
Таким образом, кажется, что атрибуты оказываются предпочтительнее элементов. Но
те специалисты, кто уже давно работает со схемами, могли заметить, что атрибуты
используются не так уж часто. Возникает вопрос: почему? Автор затрудняется
назвать точную причину, но приводит несколько аргументов:
Автор рекомендует использовать элементы для большей простоты, если только не
стоит проблема увеличения пропускной способности. В этом случае можно проверить
опытным путем, помогут ли атрибуты поднять производительность.
Нулевой атрибут
Как уже говорилось выше, атрибут можно сделать логически нулевым, если он
будет необязательным. В листинге 3 приведена схема с атрибутом, который может
быть нулевым, а в листинге 4 даны примеры экземпляров, один из которых имеет
некоторое значение в поле, а другой — нет.
Листинг 3. Схема TypeWithNullAttribute
Листинг 4. Экземпляры TypeWithNullAttribute
Атрибут со значением:
Атрибут, переданный как нулевой:
Из этих примеров видно, что в схеме нулевой атрибут объявлен очень просто.
Экземпляр нулевого атрибута также выражен очень просто — он отсутствует.
Нулевые элементы
Существует два способа представить нулевое значение, используя элементы: с
помощью атрибутов nillable=»true» или minOccurs=»0″. В листинге 5 показана
схема для оператора TypeWithNullElements, содержащая по одному элементу для
каждого из стилей полей, которые могут иметь нулевое значение.
Листинг 5. Схема для TypeWithNullElements
В листинге 6 показаны экземпляры для TypeWithNullElements. Первая из них
содержит нормальные значения, а вторая — нулевые.
Листинг 6. Экземпляры TypeWithNullElements
Элементы со значениями:
Элементы с нулевыми значениями:
Как и необязательный атрибут, элемент с атрибутом minOccurs=»0″, имеющий
нулевое значение, просто отсутствует в экземпляре XML. Это способствует
уменьшению размера сообщения, в отличие от того варианта, когда элемент
определяется с помощью атрибута nillable=»true». Атрибут nillableElem, даже
имея нулевое значение, включает поле для значения, которое показывает, что
значение этого атрибута действительно равно нулю.
Когда атрибут nillable=»true» оказывается полезен
Листинг 7. Схема для элементов массива, значение которых может быть
нулевым
Листинг 8. Экземпляр XML для элементов массива, значение которых
может быть нулевым
Заключение
Существует три способа представления нулевых полей в схеме XML:
необязательные атрибуты, элементы minOccurs=»0″ и элементы nillable=»true».
Каждый из них используется в определенной ситуации. Необязательный атрибут
используется в случае простого типа, значение которого может быть равно нулю;
элемент minOccurs=»0″ — в случае сложного типа, значение которого может быть
равно нулю, если требуется сэкономить место; элемент nillable=»true» — если
нулевое значение должно иметь определенное поле (например, когда оно входит в
состав массива).
Ресурсы
Мы можем контролировать, каким образом элементы должны использоваться в XML документах. Это позволяют сделать индикаторы.
Всего существует семь индикаторов:
Индикаторы очередности
Индикаторы очередности, как ясно из названия, используются для определения очередности появления элементов в XML документе.
Индикаторы частотности
Индикаторы частотности используются для того, чтобы определить то, как часто элементы могут появляться в XML документах.
Примечание: Для всех «порядковых» и «групповых» индикаторов (any, all, choice, sequence, group name и group reference) значением по умолчанию для maxOccurs и minOccurs является 1.
В приведенном выше примере указывается, что элемент «child_name» в элементе «person» может использоваться минимум один раз (значение по умолчанию для индикатора minOccurs — 1) и максимум 10 раз.
В приведенном выше примере указывается, что элемент «child_name» в элементе «person» может использоваться минимум 0 раз и максимум 10 раз.
Совет: Чтобы разрешить использовать какой-то элемент неограниченное число раз, используется выражение maxOccurs=»unbounded».
XML файл «Myfamily.xml»:
Приведенный XML файл содержит корневой элемент «persons». Внутри этого корневого элемента у нас есть три элемента «person». Каждый элемент «person» должен содержать элемент «full_name» и может содержать до 5 элементов «child_name».
А вот его файл схемы «family.xsd»:
Индикаторы группирования
Индикаторы группирования используются для определения связанных наборов элементов.
Группы элементов определяются при помощи декларации group следующим образом:
Внутри такой декларации необходимо определять элемент all, choice или sequence. В следующем примере определяется группа с именем «persongroup», которая определяет группу элементов, которые должны появляться точно в указанном порядке:
После того как группа элементов была определена, вы можете использовать ее в других определениях:
Группы атрибутов определяются при помощи декларации attributeGroup:
В следующем примере определяется группа атрибутов с именем «personattrgroup»:
После того как группа атрибутов была определена, вы можете использовать ее в других определениях:
В этой главе будет показано, как писать XML схемы. Также вы узнаете, что схемы можно писать разными способами.
XML документ
Давайте посмотрим на следующий XML документ под названием «shiporder.xml»:
Приведенный выше XML документ состоит из корневого элемента shiporder с обязательным атрибутом orderid. Элемент shiporder содержит три дочерних элемента: orderperson, shipto и item. Элемент item используется дважды и содержит элемент title, необязательный элемент note, а также элементы quantity и price.
Строка xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» говорит XML парсеру, что этот документ должен быть проверен на соответствие схеме. Строка xsi:noNamespaceSchemaLocation=»shiporder.xsd» указывает, где именно находится схема (в данном случае она находится в той же папке, что и файл «shiporder.xml»).
Создание XML схемы
Теперь для приведенного выше XML документа создадим XML схему.
Создадим новый файл, который назовем «shiporder.xsd». Для создания XML схемы будем просто следовать за структурой XML документа и определять каждый встреченный элемент. Начнем со стандартной XML декларации, за которой опишем элемент xs:schema, который и определяет саму схему:
Здесь мы используем стандартное пространство имен (xs) и URI, ассоциированный с этим пространством имен, который имеет стандартное значение http://www.w3.org/2001/XMLSchema.
Теперь мы должны определить элемент shiporder. У этого элемента есть атрибут, и он содержит другие элементы, поэтому мы рассматриваем его как элемент составного типа. Определения дочерних элементов элемента shiporder поместим в декларацию xs:sequence, что задает жесткую последовательность подэлементов:
Теперь определим элемент orderperson, который будет простого типа (так как он не содержит ни атрибуты, ни другие элементы). Его тип (xs:string) имеет префикс пространства имен, ассоциированного с XML схемой, что указывает на использование предопределенного типа данных:
Теперь нам нужно определить два элемента составного типа: shipto и item. Начнем с определения элемента shipto:
При помощи схем мы можем определить число возможных вхождений любого элемента. В этом нам помогут атрибуты maxOccurs и minOccurs. Атрибут maxOccurs задает максимальное число вхождений элемента, а атрибут minOccurs задает минимальное число вхождений. По умолчанию значение обоих атрибутов равно 1.
Теперь определим элемент item. Этот элемент может использоваться неограниченное число раз внутри элемента shiporder. Определить такую особенность элемента item позволяет присваивание атрибуту maxOccurs значения «unbounded». Это означает, что элемент item может использоваться столько раз, сколько нужно автору документа. Обратите внимание, что элемент note опционален. Определим это установив атрибут minOccurs в нулевое значение:
Теперь мы можем декларировать атрибут элемента shiporder. Поскольку это обязательный атрибут, используем определение use=»required».
Примечание: Атрибуты должны всегда декларироваться последними:
Вот полный код файла схемы «shiporder.xsd»:
Разделение схемы
Предыдущий способ компоновки схемы весьма прост, однако, когда документ достаточно сложен, при подобном способе соответствующая схема может оказаться довольно громоздкой, что сильно скажется на удобстве ее чтения и поддержки.
Следующий способ компоновки схемы заключается в том, что сначала определяются все элементы и атрибуты, а затем на эти определения создаются ссылки при помощи атрибута ref.
Ниже приводится новая компоновка файла схемы («shiporder.xsd»):
Использование поименованых типов
Третий способ компоновки схемы предполагает определение классов или типов, которые позволяют повторное использование определений элементов. Это становится возможным, если дать имена элементам simpleTypes и complexTypes, а затем указать на них при помощи атрибута type.
Третий способ компоновки файла схемы («shiporder.xsd»):
Элемент restriction указывает на то, что тип данных является производным от типов данных из пространства имен W3C XML Schema. Таким образом, следующий фрагмент кода означает, что значение элемента или атрибута должно быть строковым:
Однако гораздо чаще элемент restriction используется для накладывания ограничений на элементы. Посмотрите на следующие строки из приведенной выше схемы:
Этот фрагмент кода указывает, что значение элемента или атрибута должно быть строковым, ровно шесть символов в длину, и этими символами должны быть цифры от 0 до 9.
Индикаторы Заказать
Индикаторы заказа используются для определения порядка элементов.
Все Индикатор
индикатор указывает , что дочерние элементы могут появляться в любом порядке, и что каждый дочерний элемент должен иметь место только один раз:
Note: При использовании индикатор вы можете установить индикатор 0 или 1 , а индикатор может быть установлен только в 1 ( и описаны ниже).
Выбор индикатора
индикатор указывает , что может происходить либо один дочерний элемент или другой:
Индикатор чередования фаз
индикатор указывает , что дочерние элементы должны появляться в определенном порядке:
Есть семь показателей:
Группа Показатели
Показатели группы используются для определения связанных наборов элементов.
Элемент группы
групп элементов определяются с декларацией группы, как это:
Вы должны определить все, выбор, или последовательность элементов внутри декларации группы. Следующий пример определяет группу под названием , который определяет группу элементов , которые должны произойти в точной последовательности:
После того, как вы определили группу, вы можете ссылаться на нее в другом определении, как это:
Группы атрибутов
Атрибут группы определяются с декларацией attributeGroup, как это:
Следующий пример определяет атрибут группу под названием :
После того как вы определили группы атрибутов, вы можете ссылаться на нее в другом определении, как это:
Показатели Встречаемость
Показатели Встречаемость используются для определения, как часто может произойти элемент.
Note: Для всех и показателей (любой, все, выбор, последовательность, название группы, и группа справки) значение по умолчанию для MaxOccurs и MinOccurs 1.
MaxOccurs Индикатор
индикатор определяет максимальное количество раз может возникнуть элемент:
Приведенный выше пример показывает , что элемент может происходить как минимум один раз (значение по умолчанию для MinOccurs 1) и не более десяти раз в элемента.
MinOccurs Индикатор
индикатор определяет минимальное число раз может произойти элемент:
Приведенный выше пример показывает , что элемент может происходить как минимум ноль раз и не более десяти раз в элемента.
Tip: Чтобы разрешить элемент появляться неограниченное число раз, используйте MaxOccurs = «неограниченную» заявление:
A working example:
XML файл , который называется :
Файл XML выше содержит корневой элемент с именем . Внутри этого корневого элемента мы определили три элементы. Каждый элемент должен содержать элемент и может содержать до пяти элементов.