复合模板数据类型

COMPOSITE 数据类型由具有相同或不同数据类型的一个或多个值组成。 复合组件可以具有固定或可变 (但不能无限) 长度。 此数据类型类似于 C lLanguage 结构数据类型。

*DataType:COMPOSITE 指示模板定义复合数据类型,其成员可以是不同的数据类型。 COMPOSITE 数据类型的成员将输出为属于表示封闭上下文的元素的单个 XML 子元素。 如果每个子元素表示一个数据类型基元,则数据类型将由每个元素中的 XML 属性 xsi:type 定义。 如果将 GDL 属性定义为 DataType : COMPOSITE,则封闭上下文将是 <GDL_ATTRIBUTE> 元素。 每个 XML 子元素的元素名称将是 指令 *ElementTags 定义的相应标记。

如果 COMPOSITE 本身是另一个复合数据类型的成员,则将创建一个元素来表示该封闭上下文。 此父元素的名称将是模板分配的相应标记,该标记对应于封闭复合数据类型。

以下指令用于定义 COMPOSITE 数据类型:

  • *ElementType (必需) 。 定义每个元素的数据类型的模板的名称。 必须为每个元素指定一个数据类型。 一个或多个元素可以具有相同的数据类型。 提供的 ElementType 数应等于 *ArraySize 指定的 ArraySize 或 Max 值。

  • *RequiredDelimiter (必需) 。 一个字符串,该字符串将在语法上将每个 COMPOSITE 元素与下一个元素分开。 两个连续的分隔符将被解释为省略的元素。 不需要分隔符来指示尾随元素的省略。

    如果使用空格作为分隔符或分隔符字符串的一部分,则应非常小心。 例如,分析程序会将无关空格字符解释为指示省略的元素;由于可能看不到额外的空格,因此可能会出现奇怪的分析错误。 此外,会定期从源文件中去除多余的空格,并且由于预处理器、宏和注释处理,通常会将空格添加到输入流中。 因此,分析的实际字符串的空格字符数可能与最初指定的字符数完全不同。 不应使用制表符作为所需分隔符字符串的一部分,因为它们在输入处理过程中会定期转换为空格字符。

  • *OptionalDelimiter (可选) 。 任何包含 *OptionalDelimiter 中指定的字符且与 * RequiredDelimiter 字符串相邻的字符串都将被视为分隔符的一部分。

  • *ElementTags (必需) 。 提供的标记数应等于 *ArraySize 指定的 ArraySize 或 Max 值。 每个成员都将使用相应的标记进行标记。 如果省略一个或多个元素,此标记非常有用。 如果省略 COMPOSITE 元素,则不使用与省略元素对应的标记。 为了避免混淆客户端,请不要使用 GDL 快照保留元素名称作为标记名称。 这些保留名称为 CONSTRUCT、ATTRIBUTE 和 Personality。

  • *ArraySize (可选) 。 如果省略此指令,则将采用固定大小的 COMPOSITE。 大小将等于 *ElementType 中的模板名称数。

    使用两个整数指定可变大小的 COMPOSITE 允许的最小和最大大小。 请注意,最小大小允许零。 不允许使用大小不限的 COMPOSITE 数据类型。 不能使用 GPD 通配符 (*) 来指定大小或最大大小。

  • *ArrayLabel (可选) 。 如果指定了此指令,则 COMPOSITE 元素的列表必须用括号括起来,并以 *ArrayLabel 标签开头。 如果未在此指令中指定任何标签,则括号是可选的,并且不允许使用前言标签。

请考虑以下模板。

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

前面的模板定义了一个固定大小的复合,包含两个 SYMBOL 数据类型和一个整数。 COMPOSITE 未标记。 COMPOSITE 中的每个元素都分配有一个唯一的 ElementTag。 这些标记将标记 XML 输出中的每个元素,以帮助客户端。 每个元素与下一个元素隔开一个句点 (.) ;没有其他字符被视为分隔符的一部分。 *未指定 ArraySize,因此假定复合大小固定。 由于 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

假定使用以下RC_NAME_ID模板解释 GDL 条目。

*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>

以下示例通过使用包含一对表示时间间隔的 DATE 数据类型的 INTERVAL 数据类型来演示嵌套的复合数据类型。 每个 DATE 数据类型都是 MONTH、DAY 和 YEAR 数据类型的复合。 VACATION GDL 属性使用 INTERVAL 数据类型来表示员工可能缺席的时间段。 以下模板集合将完成这种情况。

月份模板

*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

如果使用 VACATION 模板解释此 GDL 条目,则生成的 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>