double arrow

Типы данных SOAP

В стандарте XML не предусмотрены стандартные типы данных. Из-за его гибкости нет нужды каким-либо особым образом объявлять единый набор типов данных для всех XML-документов. Каждый разработчик может сам объявить именно те типы данных, которые будут применяться в его наборе XML-документов. Однако подобные типы должны, естественно, объявляться в DTD-блоке. Так как в SOAP,-сообщениях нет DTD-блоков, то для них заранее объявлены возможные типы данных.

Структура типов для SOAP-сообщений в достаточно большой мере унаследована из словаря ХМL Schema. Данный словарь был введен в обращение корпорацией Microsoft. Он позволял пользоваться заранее определенным набором тегов и типов данных, таким образом несколько сужая функциональность XML. но приводя документы к некоему стандартизованному виду.

В SOAP мы можем применять простые и составные типы данных. Для начала следует разобраться с простыми типами, которые полностью унаследованы из XML Schema.

□ Тип boolean предназначен для реализации логических значений. По сути является перечислимым типом. В качестве допустимых значений могут использоваться только ключевые слова true и false, первое из которых обозначает истинность утверждения, второе — ложность.

□ Тип float предназначен для представления численных данных. Для хра­нения каждой численной величины этого типа отводится тридцать два бита, т. е. четыре байта. При этом значение представляется в виде произведения целого числа, чье абсолютное значение меньше или равно 16777216. и экспоненты, показатель степени которой может находиться в пределах от 104 до -149.

□ Тип double также предназначен для численных данных. Но для каждого значения этого типа отводится уже шестьдесят четыре бита, т. е. восемь байтов. Соответственно, изменяется и точность представления чисел, и возможный диапазон представимых значений.

□ Если предыдущие два типа рассматривали число в экспоненциальной форме, то тип decimal для представления численных данных использует десятичные степени. Естественно, в этом случае число представляется в виде обычной десятичной дроби. По умолчанию XML-процессоры распознают и обрабатывают восемнадцать десятичных знаков после запятой.

□ Тип timeDuration предназначен для хранения данных о времени. Значе­ние этого типа состоит из шести частей. В нем указывается год, месяц, день, часы, минуты и секунды. Вид значений этого типа описывается в стандарте ISO 8601. Порядок используется именно тот, в котором отдельные части были перечислены. Для указания года используются четыре символа, на остальные части значения времени отводится по два символа.

□ Тип гecurringDuration задает период времени, в течение которого будет с определенной частотой происходить или производиться некое действие. По сути, этот тип является набором значений типа timeDuiation.

□ Тип binary предоставляет возможность хранить и обрабатывать данные в двоичном виде, т. е. по сути, это реализация любых объектных вставок: графика, звук, видеоклипы и иные бинарные объекты.

□ Тип uriReference позволяет задавать URI (Universal Resource Identifier) в качестве содержимого какого-либо элемента. Детально структура URI описана в документах RFC 2396 и RFC 2732.

□ Тип integer предназначен для хранения целочисленных значений. Создан на основе типа decimal. Значения этого типа представляют собой конечную последовательность десятичных цифр с необязательным символом математического знака впереди. Если перед положительным числом ставится знак плюса, то он игнорируется.

□ Тип nonPositiveInteger создан на основе типа integer. Этот тип предназначен для хранения неположительных целочисленных данных. Неположительные целочисленные данные объединяют нуль и все целые отрицательные числа.

□ На основе вышеуказанного типа создан тип negativeInteger. Используется для представления отрицательных целых чисел. Данные этого типа представляют собой конечную последовательность десятичных цифр со знаком минус впереди.

□ Тип long создан на основе типа integer. Он хранит данные не в форме последовательности символов цифр, а как единое численное значение. Естественно, это налагает ограничения на диапазон хранимых данных. Для хранения одного числа отводится восемь байтов. Так как величины данного типа могут быть как отрицательными, так и положительными, границы допустимого диапазона значений установлены от 9 223 372 036 854 775 807 до -9 223 372 036 854 775 808.

□ На основе типа long построен тип int. Он также предназначен для представления целых чисел, но для хранения каждого числа отведено четыре байта. Таким образом, величины данного типа могут находиться в промежутке от 2 147 483 647 до -2 147 483 648. Лексически его значения представляют собой конечную последовательность десятичных цифр с необязательным символом математического знака в начале.

□ Если под хранение целого числа отводить не четыре байта, а два — мы получим тип short, декларируемый на основе типа int. Промежуток допустимых значений для этого типа лежит от 32 767 до -32 768.

□ Тему экономии памяти продолжает тип byte, созданный на базе типа short. Как следует из его названия, под хранение одного целого числа отводится один байт. Следовательно, мы можем использовать только числа от 127 до - 128.

□ Тип nonNegativeIntegег основан на типе integer и предназначен для хранения неотрицательных целых чисел. По сути, мы просто жестко задаем нулевое значение свойства minInciusive. Все остальное остается без изменений.

□ На базе указанного типа создан тип unsignedLong. Он предназначен для хранения без знакового целого числа. Максимальное возможное значение свойства mахInclusive — 18 446 744 073 709 551 615. Минимальное, естественно — 0.

□ Тип unsignedInt является производным от типа unsignedLong. Разница между ними заключается в количестве байтов, отводимых под хранение одного числа. Тип unsignedInt — вдвое экономнее. Данные этого типа лежат в промежутке от нуля до 42 949 672 95 включительно.

□ Тип unsignedShort, построенный на базе только что рассмотренного нами типа unsignedInt, под одно число отводит всего два байта. Но так как мы используем в данном случае без знаковые числа, то максимально возможное число этого типа — 65 535.

□ Последним из типов, предназначенных для хранения целых без знаковых чисел, является unsignedByte. Легко понять, что для хранения отдельного числа этого типа применяется всего один байт. Таким образом, мы можем использовать рассматриваемый тип для чисел в промежутке от 0 до 255 включительно.

□ Тип positiveInteger предназначен для хранения и представления положительных целых чисел. Он построен на основе типа nonNegativeInteger. При хранении данных этого типа опциональный знак плюса и нули, стоящие в начале числа, игнорируются.

□ Тип timeInstant предназначается для отображения данных, хранящих информацию о времени и дате. Таким образом, если мы используем рассматриваемый тип для хранения точки времени 13 часов 20 минут 31 марта 2000 года в часовом поясе, смешенном на пять часов относительно времени но Гринвичу, отображаться это значение будет так: 2000-0 3-31113:20:00-05:00.

□ Тип time позволяет хранить данные только о времени, без указания даты. Таким образом, то же самое время 13:20 в искомом часовом поясе будет отображаться так: 13:20:00-05:00.

□ Тип timePeriod используется для обработки и отображения неких промежутков времени, для которых явно задано время начала и окончания.

На самом деле данный тип не рекомендуется напрямую использовать в XML-документах, созданных по спецификации XML Schema. Рекомендуется использовать типы данных, построенные на его основе.

□ Тип date является первым из рассматриваемых нами типов данных, созданных на основе типа timePeriod. Он позволяет указывать промежуток времени величиной в одни сутки, который начинается в полночь указанной даты суток и заканчивается в полночь следующих суток. То есть, значение 2000-12-06 указывает не на точку времени, а на временной промежуток, который начинается в полночь шестого декабря двухтысяч­ного года и длится до полуночи седьмого декабря двухтысячного года. В спецификации XML Schema сказано, что данный тип предназначен для обработки суточного интервала времени "вне зависимости от количества часов в этом дне". В качестве данных этого типа могут использоваться только даты стандартного Григорианского календаря в виде yyyy-mm-dd. Если необходимо использовать дату до нашей эры, то перед годом ставится знак минуса.

□ Тип month основан на типе timePeriod. Он предназначен для определе­ния промежутков времени длиною в месяц. Этот промежуток начинается в полночь первого дня указанного месяца и заканчивается в полночь первого дня следующего месяца, не включая ее. Данные этого типа имеют вид строк формата yyyy-mm. Таким образом, чтобы обозначить декабрь двухтысячного года, мы должны использовать строку 2000-12.

□ Тип year используется для хранения годичных промежутков времени. Данные этого типа указываются в виде строк формата yyyy. Искомый промежуток времени начинается в полночь первого дня указанного года, а заканчивается в полночь первого дня следующего года, не включая ее. Таким образом, весь прошедший двухтысячный год мы можем обозначить строкой 2000. Если необходимо указать годы до нашей эры, то перед номером этого года, в котором, кстати, может быть больше четырех цифр, следует поставить знак минуса.

□ Тип century предназначен для обработки столетий. При этом значения данного типа представляются в виде двух цифр, являющихся обозначением века в нумерации годов. Таким образом, если мы хотим задать двадцатый век, то мы должны использовать значение 19. Данный промежуток времени начинается в полночь первого дня указанного столетия, а заканчивается в полночь первого дня следующего века, не включая ее.

□ Тип recurringDate предназначается для обработки неких ежегодно по­вторяющихся дат. Значениями данного типа являются строки формата мм-dd. То есть, если мы задаем значение 12-06,то указываем ежегодно повторяющуюся дату — шестое декабря. Естественно, при помощи величин этого типа чрезвычайно удобно задавать самые различные годовщины, такие, как дни рождения и т. п.

□ Тип recurringDay позволяет задавать ежемесячно повторяющиеся дни. Мы указываем только число, а затем оно будет автоматически обрабатываться каждый месяц. Этот тип генерируется на основе типа recurгinqDuration. Данные этого типа записываются в виде строк из двух символов, которые обозначают число повторяющегося дня.

Теперь перейдем к рассмотрению сложных типов данных. К ним относятся массивы, перечислимые списки и составные типы данных. Начнем мы с ознакомления с перечислимыми списками.

Перечислимые списки функционально весьма похожи на Enumeration –классы, которые используются в Visual Basic.NET. В этих списках могут храниться значения любых типов, кроме типа Boolean. Естественно, элементы списка должны иметь один и тот же тип. В качестве примера можно привести хранение в подобном списке цветов продаваемых машин. Тогда в SOAP-сообщении будет находиться приблизительно следующий фрагмент кода:

<element name="CarColor" type="tns:CarColor" />

<simpleType name= "CarColor" base="xsd: String''>

<enumeration value="Red" />

<enumeration value="White” />

<enumeration value="Blue” />

</simpleType>

<car>

<Model>Ferrary</Model>

<CarColor>Red</CarColor>

</Car>

В этом примере мы объявляем перечислимый тип CarColor, который создается на основе базового типа String. Затем при помощи тегов <Enumeration> задаются конкретные значения, входящие в перечислимый список. Естественно, эти теги заключаются между стартовым и закрывающим тегами <simpleType>. А затем уже при указании данных об объекте Cаr мы используем одно из предустановленных значений заранее объявленного перечисляемого списка.

Теперь перейдем к составным типам. Теоретически, массивы в SOAP тоже относятся к составным типам. Но разработчикам все-таки привычнее под составными типами понимать именно определяемые структуры. Если говорить строго, то структура является составным значением, элементы которого идентифицируются только их наименованиями, причем, эти наименования должны быть уникальны для каждого элемента структуры. По сути, структуры напоминают классы, но их нельзя назвать полноценными классами, так как они не могут включать в себя методы и свойства. Когда мы в предыдущем примере указывали информацию о конкретной машине, то неявно подразумевалось, что объект Car как раз и попадает под определение составного типа. В том случае, когда приложение, принимающее SOAP- сообщение, заранее знает его структуру, нет смысла описывать все составные типы данных. Однако так может быть далеко не всегда, поэтому если в цепочке получателей SOAP-сообщения есть приложение, которое не изве­щено о структуре сообщения, следует объявлять используемые составные типы.

Но перейдем к примеру определения составного типа данных. Попробуем создать структуру, которая с достаточно малой степенью детализации описывает, скажем, книги, продаваемые неким магазином. На самом деле при продаже книг в корпоративных базах данных хранится достаточно много информации, но сейчас мы ограничимся малой ее долей в пользу более легкой читаемости кода примера.

<element name="Book">

<complехТуре>

<element name="author" type="xsd:string">

<element name="name" type="xsd:string">

<element name="price" type="xsd:float">

</complexType>

<element/>

<Book>

<author>Гибсон У.</author>

<паmе>Нейромантик</name>

<price>58.75</price>

</Book>

Легко заметить, что объявление структуры составного типа производится между тегами <complexType> и </complexType>. Мы задаем два элемента строчного типа, в которых хранятся наименование книги и имя ее автора, и один элемент числового типа, в котором будет храниться цена продаваемой книги. После объявления составного типа располагается сам экземпляр значения этого типа. В SOAP-сообщении передается информация о книге Уильяма Гибсона "Нейромантик", которая продается но цене 58.75.

Теперь обратимся к использованию массивов. Массив тоже является состав­ным типом, элементы которого идентифицируются только своим порядко­вым номером. В качестве элементов массива могут использоваться не только значения простых типов, но также структуры и другие массивы.

Любой массив в SOAP должен объявляться при помощи типа SOAP-ENC: Array. Вот простейший пример объявления массива из трех элементов целочисленного типа:

<element name="MyArray" type="SOAP-ENC:Array" />

<MyArray SOAP-ENC:arrayType="xsd:int[3]">

<item>1</item>

<item>2</item>

<item>3</item>

</MyArray>

Естественно, SOAP позволяет определять и многомерные массивы данных. Объявление массива размером "два на три", состоящего из элементов строкового типа, может выглядеть следующим образом:

<MyStringArray SQAP-ENC:arrayType=”xsd: String[2,3] ">

Таким образом, мы разобрали все типы данных, которые применяются в рамках создания SOAP-сообщений.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



Сейчас читают про: