Поделиться через


Типы данных составного шаблона

Тип данных COMPOSITE состоит из одного или нескольких значений, имеющих одинаковые или разные типы данных. Составные компоненты могут иметь фиксированную или переменную (но не бессрочную) длину. Этот тип данных аналогичен типу данных структуры C lLanguage.

*DataType: COMPOSITE направляет шаблон для определения составного типа данных, члены которого могут быть разных типов данных. Элементы типа данных COMPOSITE будут выводиться в виде отдельных дочерних элементов XML, принадлежащих элементу, представляющего включающий контекст. Если каждый дочерний элемент представляет тип данных-примитив, тип данных будет определяться XML-атрибутом xsi:type в каждом элементе. Если атрибут GDL определен как DataType : COMPOSITE, то включающий контекст будет элементом <GDL_ATTRIBUTE> . Имя каждого дочернего xml-элемента будет соответствующим тегом, определенным директивой Директива: *ElementTags.

Если объект COMPOSITE сам является членом другого составного типа данных, будет создан элемент для представления этого включающего контекста. Именем этого родительского элемента будет соответствующий тег, назначенный шаблоном, который соответствует включающем составной типу данных.

Для определения типа данных COMPOSITE используются следующие директивы:

  • *ElementType (обязательный). Имя шаблона, определяющего типы данных каждого из элементов. Для каждого элемента необходимо указать один тип данных. Один или несколько элементов могут иметь один и тот же тип данных. Число предоставленных значений ElementType должно быть равно значению ArraySize или Max, заданному параметром *ArraySize .

  • *RequiredDelimiter (обязательно). Строка, которая синтаксически отделяет каждый элемент COMPOSITE от следующего. Два последовательных разделителя будут интерпретироваться как опущенный элемент. Разделители не требуются для указания пропусков конечных элементов.

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

  • *OptionalDelimiter (необязательный). Любая строка, состоящая из символов, указанных в *OptionalDelimiter , которая отображается рядом со строкой *RequiredDelimiter , будет считаться частью разделителя.

  • *ElementTags (обязательно). Число предоставленных тегов должно быть равно значению ArraySize или Max, заданному параметром *ArraySize . Каждому элементу будет присвоен соответствующий тег. Это удобно, если один или несколько элементов опущены. Если элементы COMPOSITE опущены, тег, соответствующий опущенным элементам, не используется. Чтобы избежать путаницы с клиентом, не используйте GDL snapshot зарезервированные имена элементов в качестве имен тегов. Зарезервированные имена: CONSTRUCT, ATTRIBUTE и Personality.

  • *ArraySize (необязательно). Если эта директива опущена, предполагается композитный фиксированный размер. Размер будет равен количеству имен шаблонов в *ElementType.

    Используйте два целых числа, чтобы указать минимальный и максимальный допустимый размер для составного объекта переменной. Обратите внимание, что для минимального размера допускается ноль. Составные типы данных неограниченного размера не допускаются. Нельзя использовать подстановочный знак GPD (*) для указания размера или максимального размера.

  • *ArrayLabel (необязательно). Если указана эта директива, список элементов COMPOSITE должен быть заключен в круглые скобки и предваряться меткой *ArrayLabel . Если в этой директиве не указана метка, круглые скобки являются необязательными, а метка предварительного добавления не допускается.

Рассмотрим следующий шаблон.

*Template:  QUALNAME_EX
{
    *Type:  DATATYPE
    *DataType:   COMPOSITE
    *ElementType: (SYMBOL, SYMBOL, INTEGER)
    *RequiredDelimiter: "."
    *ElementTags: (feature, option, resourceID)
}

Предыдущий шаблон определяет фиксированный размер, составной из двух типов данных SYMBOL и одного целого числа. Объект COMPOSITE не помечен. Каждому элементу в составной части присваивается уникальный элемент ElementTag. Эти теги помечают каждый элемент в выходных данных XML, чтобы помочь клиенту. Каждый элемент отделяется от следующего ровно одной точкой (.); никакие другие символы не считаются частью разделителя. *ArraySize не указан, поэтому предполагается фиксированный размер COMPOSITE. Так как размер COMPOSITE является фиксированным, пропуск члена не допускается.

*DataType: составные шаблоны не создают соответствующую схему. Вместо этого используется схема шаблонов, именованных в директиве *ElementType .

Например, рассмотрим шаблон SYMBOL, который определяется следующим образом.

*Template:  SYMBOL
{
    *Type:  DATATYPE
    *DataType:   FILTER_TYPE
    *ElementType:  XML_STRING
    *FilterTypeName: "SYMBOLNAME"
}

И рассмотрим следующую запись GDL.

*rcNameID:     ( RESDLL.stdname.467 )  

Или рассмотрим следующую запись GDL без необязательных круглых скобок.

*rcNameID:     RESDLL.stdname.467

Предположим, что запись GDL интерпретируется с помощью следующего шаблона RC_NAME_ID.

*Template:  RC_NAME_ID
{
    *Name:  "*rcNameID"
    *Type:  ATTRIBUTE
    *ValueType:  QUALNAME_EX
    *Additive: LEAST_TO_MOST_RECENT
}

Выходные данные XML будут следующими.

    <GDL_ATTRIBUTE Name="*rcNameID"  >
        <feature  xsi:type="GDLW_string">RESDLL</feature>
        <option  xsi:type="GDLW_string">stdname</option>
        <resourceID  xsi:type="GDLW_int">467</resourceID>
    </GDL_ATTRIBUTE>

В следующем примере показаны вложенные составные типы данных с использованием типа данных INTERVAL, который содержит пару типов данных DATE, представляющих интервал времени. Каждый тип данных DATE является составным типом данных MONTH, DAY и YEAR. Тип данных INTERVAL используется атрибутом VACATION GDL для выражения периода времени, который может отсутствовать у сотрудника. Следующая коллекция шаблонов позволит выполнить эту задачу.

Шаблон месяца

*Template:  MONTHS
{
    *Type:  DATATYPE
    *DataType:   ENUMERATOR
    *XMLDataType: "months"
    *EnumeratorList: (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)
}

Шаблон "День"

*Template:  DAY
{
*Inherits: INTEGER
*MinValue: 1
*MaxValue: 31
}

Шаблон года

*Template:  YEAR
{
*Inherits: INTEGER
*MinValue: 1900
*MaxValue: 2100
}

Шаблон даты

*Template:  DATE
{
    *Type:  DATATYPE
    *DataType:   COMPOSITE
    *ElementType: (MONTHS, DAY, YEAR)
    *RequiredDelimiter: "-"
    *ElementTags: (month, day, year)
}

Шаблон интервала

*Template:  INTERVAL
{
    *Type:  DATATYPE
    *DataType:   ARRAY
    *ElementType:  DATE
    *RequiredDelimiter: "to"
    *OptionalDelimiter: "<20 09>"
    *ElementTags: (start_date, end_date)
    *ArraySize: 2
}

Шаблон "Отпуск"

*Template:  VACATION
{
    *Name:  "*VacationDates"
    *Type:  ATTRIBUTE
    *ValueType:  INTERVAL
}

Рассмотрим следующую запись GDL.

*VacationDates:  Dec-20-2001 to Jan-3-2002

Если эта запись GDL интерпретируется с помощью шаблона VACATION, выходные данные XML будут вытекать следующим образом.

    <GDL_ATTRIBUTE Name="*VacationDates"  >
        <start_date >
            <month  xsi:type="GDLW_months">Dec</month>
            <day  xsi:type="GDLW_int">20</day>
            <year  xsi:type="GDLW_int">2001</year>
        </start_date>
        <end_date >
            <month  xsi:type="GDLW_months">Jan</month>
            <day  xsi:type="GDLW_int">3</day>
            <year  xsi:type="GDLW_int">2002</year>
        </end_date>
    </GDL_ATTRIBUTE>