SGML Declaration

SGML декларация определяет самый нижний, лексический уровень SGML-документа:

  • используемый алфавит
    • спецсимволы
    • разделители

ПримерПравить

Рассмотрим основные части SGML-декларации, на основе этого минимального примера.

<code-xml> <!SGML "ISO 8879:1986"

  CHARSET
     BASESET "ISO 646-1983//CHARSET International Reference
              Version (IRV)//ESC 2/5 4/0"
     DESCSET
         0    9 UNUSED
         9    2    9
        11    2 UNUSED
        13    1   13
        14   18 UNUSED
        32   95   32
       127    1 UNUSED
  CAPACITY PUBLIC "ISO 8879-1986//CAPACITY Reference//EN"
  SCOPE DOCUMENT
  SYNTAX PUBLIC "ISO 8879-1986//SYNTAX Reference//EN"
  FEATURES
     MINIMIZE DATATAG  NO  OMITTAG  NO  RANK     NO
              SHORTTAG NO
     LINK     SIMPLE   NO  IMPLICIT NO  EXPLICIT NO
     OTHER    CONCUR   NO  SUBDOC   NO  FORMAL   NO
  APPINFO NONE

> </code-xml>

Итак, сама SGML-декларация всегда кодируется в синтаксисе «Reference Concrete Syntax», т. е. состоит из набора ключевых слов, чисел и литералов, разделенных пробелами, символами табуляции и перевода строк и комментариями, которые начинаются и оканчиваются «--» (разделителем COM). Декларация начинается с заголовка содержащего литерал, указывающий версию стандарта. Правда сейчас версия стандарта всего одна (и маловероятно, что появится другая версия), поэтому, можно считать, что этот литерал должен всегда быть «ISO 8879:1986», что означает опубликованную в 1986, версию ISO стандарта № 8879. Далее рассмотрим остальные разделы.

CHARSETПравить

Определяет алфавит документов. Состоит из раздела «BASESET», определяющего базовый набор символов (алфавит), как правило это ASCII (т. е. ISO 646) и раздела «DESCSET» (described character set portion), определяющего правила отображения алфавита документа на базовый алфавит. DESCSET-правила просты, строчка «kk mm nn», означает, что диапазон символов с кодами в алфавите документа от kk до kk+mm-1 отображается на диапазон символов в базовом алфавите с кодами от nn до nn+mm-1. Третья колонка, кроме кода стартового символа в базовом алфавите, может содержать:

константу «UNUSED»
Это значит, что указанные символьные коды являются неопределенными, а соответствующие символы есть «non-SGML characters».
строковый литерал
Это значит, что символы с указанными кодами являются незначительными ("non-significant SGML data character"), т.е. могут встречаться в документе, но не могут нести никакой разметочной нагрузки, например, не могут служить разделителями. Так, следующая строчка позволит использовать в документах верхнюю половину ASCII-таблицы:
     128  128  "High-order characters"

CAPACITYПравить

Определяет различные мощностные ограничения на свойства документа. Например, «ELEMCAP» ограничивает произведение числа различных SGML-элементов на свойство «NAMELEN» (см. #SYNTAX). Аналогичным образом, можно задать и другие ограничения: «ENTCAP», «ENTCHCAP», «ELEMCAP», «GRPCAP», «EXGRPCAP», «EXNMCAP», «ATTCAP», «ATTCHCAP», «AVGRPCAP», «NOTCAP», «NOTCHCAP», «IDCAP», «IDREFCAP», «MAPCAP», «LKSETCAP», «LKNMCAP». Можно использовать параметр «TOTALCAP», для ограничения сверху всех вышеупомянутых параметров.

Можно использовать «Reference Capacity Set»

  CAPACITY PUBLIC "ISO 8879-1986//CAPACITY Reference//EN"

который установит все ограничения в 35000.

А можно и вовсе отключить эти ограничения:

  CAPACITY NONE  -- Capacities are not restricted in XML --

SCOPEПравить

Определяет, к чему будет применяться «concrete syntax», определяемый в следующем разделе (#SYNTAX) Тут всего два варианта:

SCOPE DOCUMENT
«concrete syntax» применяется целиком, ко всему SGML-документу, включая «document type declaration».
SCOPE INSTANCE
«concrete syntax» применяется только к части документа, следующей за прологом, т. е. не применяется к «document type declaration».

SYNTAXПравить

Определяет «concrete syntax».

Стандартные синтаксисыПравить

Можно воспользоваться четыремя стандартными синтаксисами, определенными в стандарте SGML:

the Reference Concrete Syntax
  SYNTAX PUBLIC "ISO 8879-1986//SYNTAX Reference//EN"
the Core Concrete Syntax
отличается от «the Reference Concrete Syntax» отсутствием определений «Short Reference Delimiters».
  SYNTAX PUBLIC "ISO 8879- 1986//SYNTAX Core//EN"
the Multicode Basic Concrete Syntax
отличается от «the Reference Concrete Syntax» наличием некоторого количества определений символов, подавляющих разметку.
  SYNTAX PUBLIC "ISO 8879- 1986//SYNTAX Multicode Basic//EN" 
the Multicode Core Concrete Syntax
отличается от «the Reference Concrete Syntax» наличием некоторого количества определений символов, подавляющих разметку и отсутствием определений «Short Reference Delimiters».
  SYNTAX PUBLIC "ISO 8879- 1986//SYNTAX Multicode Core//EN"

Далее, стандартный синтаксис можно донастраивать, например, строка

  SWITCHES  47 92

приведет к переносу смысла символа с кодом 47 («/») на символ с кодом 92 («\»). При этом (если использовался стандартный синтаксис) разделитель «ETAGO» (закрывающий тэг элемента) станет «\>» вместо «/>», а разделитель «NET» сменится с «/» на «\». Заметим, что это не простая трансляция одних символьных кодов в другие — значения строковых литералов, например, при этом не изменятся. Также это не «обмен», т. е. чтобы «обменять смыслы» двух символов, нужно соответственно повторить эту директиву, или продолжить:

  SWITCHES  47 92 92 47

Cледующий пример, обменяет «стандартные» для всех SGML/XML разметок символы «<" и ">» на «{» и «}».

SYNTAX PUBLIC "ISO 8879-1986//SYNTAX Multicode Basic//EN"
SWITCHES 60 123 123 60 62 125 125 62

Variant Concrete SyntaxПравить

Можно декларировать конкретный синтаксис, определив его «с нуля». Для этого, рассмотрим определение самого «The Reference Concrete Syntax»:

  SYNTAX
     SHUNCHAR CONTROLS
              0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
              19 20 21 22 23 24 25 26 27 28 29 30 31 127 255
     BASESET "ISO 646-1983//CHARSET International Reference
              Version (IRV)//ESC 2/5 4/0"
     DESCSET
         0  128   0
     FUNCTION
        RE            13
        RS            10
        SPACE         32
        TAB SEPCHAR    9
     NAMING
        LCNMSTRT ""
        UCNMSTRT ""
        LCNMCHAR "-."
        UCNMCHAR "-."
        NAMECASE GENERAL YES
                 ENTITY  NO
     DELIM
        GENERAL SGMLREF
        SHORTREF SGMLREF
     NAMES SGMLREF
     QUANTITY SGMLREF 

SHUNCHARПравить

ISO 8879 требует избегать («Clause 4.297») «shunned» («опасных») символов, «поскольку некоторые системы могут ошибочно трактовать такие символы как управляющие». В этом разделе, перечисляются коды таких символов. Дополнительно, можно использовать ключевое слово «CONTROLS» в разделе «SHUNCHAR», что означает, что любой символ в алфавите документа, чей код является кодом управляющего символа, является «shunned» символом (в дополнении к перечисленным вручную). Так что раздел «SHUNCHAR» из предыдущего примера можно эквивалентно переписать в виде:

    SHUNCHAR 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
             19 20 21 22 23 24 25 26 27 28 29 30 31 127 255

или

    SHUNCHAR CONTROLS 255

Отсутствие «shunned» символов декларируется как:

    SHUNCHAR NONE

The Syntax-Reference Character SetПравить

Алфавит конкретного синтаксиса, определяется аналогично алфавиту документа, через директивы BASESET и DESCSET. Вот пример «the syntax-reference character set» полностью эквивалентного ISO 646:

  BASESET "ISO 646-1983//CHARSET International Reference
          Version (IRV)//ESC 2/5 4/0"
  DESCSET
          0  128   0

FUNCTIONПравить

В этом разделе определяются функциональные символы, имеющие особую важность, при разборе SGML-документа. Обязательно определить «RE», «RS», «SPACE», причем именно в этом порядке, далее можно определять дополнительные именованные символы, например «TAB»:

FUNCTION RE                    13
         RS                    10
         SPACE                 32
         TAB       SEPCHAR     9

причем для «дополнительных» именованных символов можно указывать их роль:

SEPCHAR
разделитель, «white space»;
MSSCHAR
«markup suppression character» — по сути «escape character», т. к. блокирует спецзначение у следующего за ним символа. Т.е. после обьявления
BACKSL MSSCHAR   92
можно ввести амперсанд как «\&».
MSOCHAR, MSICHAR
также «markup suppression character», только «действующие на интервале». Так, после декларации
        MSO MSOCHAR   96
        MSI MSICHAR   36
строчка
`<foo></foo>$
будет интерпретирована как поток символов, без разбора на элементы.
FUNCHAR
нейтральный управляющий символ.

Коды символов в этот раздел можно вводить как численно (кроме трех упомянутых обязательных символов), так и с помощью механизма именованных ссылок, например:

   &#SPACE;
 

NAMINGПравить

Этот раздел определяет символы, которые могут использоваться в именовании (элементов, сущностей и т. п.).

Например, этот блок объявляет, что имена могут быть алфавитно-цифровыми, начинаясь с буквы или цифры «7», могут содержать «.» и «-», причем имена, кроме имен entity, чувствительны к регистру.

 NAMING LCNMSTRT  "7"
        UCNMSTRT  "7"
        LCNMCHAR  "-."
        UCNMCHAR  "-."
        NAMECASE  GENERAL     YES
                  ENTITY      NO

Вообще, по умолчанию, имена являются алфавитно-цифровыми, начинающимися с буквы, но можно также начинать имена с символов встречающихся в литералах параметров «LCNMSTRT» и «UCNMSTRT», и использовать в именах символы из литералов «LCNMCHAR» и «UCNMCHAR». Парность параметров с префиксами «LC» и «UC» объясняется тем, что таким способом для «дополнительных разрешенных» символов определяется, кто из них «lower case», а кто «upper case» соответственно.

DELIMПравить

Если требуется использовать стандартные SGML-разделители, то достаточно сделать следующее:

DELIM
        GENERAL SGMLREF

Таким образом, будут определены следующие стандартные разделители:

           AND         "&"        
           COM         "--"        
           CRO         "&#"        
           DSC         "]"        
           DSO         "["        
           DTGC        "]"
           DTGO        "["
           ERO         "&"        
           ETAGO       "</"
           GRPC        ")"
           GRPO        "("
           LIT         "        
           LITA        ""
           MDC         ">"        
           MDO         "<!"        
           MINUS       "-"
           MSC         "]]"        
           NET         "/"
           OPT         "?"        
           OR          "|"        
           PERO        "%"
           PIC         ">"        
           PIO         "<?"        
           PLUS        "+"
           REFC        ";"
           REP         "*"        
           RNI         "#"
           SEQ         ","
           STAGO       "<"
           TAGC        ">"
           VI          "="


Если мы захотим переопределить некоторые разделители, то это также можно сделать, учитывая, что длина строки-разделителя не должна быть больше LITLEN=240, и не должна состоять только из функциональных символов. Например, следующим образом мы меняем стандартные разделители «GRPO» и «GRPC», которые по умолчанию есть "(" и «)» на фигурные скобки:

DELIM GENERAL   SGMLREF
           GRPO   "{"
           GRPC   "}"


Аналогично определяются SHORTREFы. Отказаться от них можно с помощью

       SHORTREF NONE

А стандартный набор, включаемый строкой

       SHORTREF SGMLREF

включает следующие определения:

       SHORTREF NONE
           "&#SPACE;"    "&#TAB;"    "&#RE;"    "&#RS;"
           "&#RS;&#RE;"  "&#RS;B"    "B&#RE;"   "B&#RE;"    "BB"
           "    "#"    "%"   ""   "("   ")"  "*"   ","   "-"
           ":"    ";"    "="   "@"   "+"   "["  "]"
           "^"    "_"    "{"   "|"   "}"   "~"  "--"

Дополнительные shortrefы определяются следующим образом:

  SHORTREF SGMLREF
           "\"
           "---"

NAMESПравить

Стандартный набор зарезервированых имен

ANY		ATTLIST		CDATA		CONREF
CURRENT        DEFAULT		DOCTYPE		ELEMENT
EMPTY	        ENDTAG		ENTITIES	ENTITY
FIXED	        ID		IDLINK		IDREF
IDREFS	        IGNORE		IMPLIED		INCLUDE
INITIAL        LINK		LINKTYPE	MS
NAME	        NAMES		NDATA		MNTOKEN
NMTOKENS       MD		NOTATION	NUMBER
NUMBERS        NUTOKEN		NUTOKENS	O
PCDATA	        PI		POSTLINK	PUBLIC	
RCDATA	        REQUIRED	RESTORE		SDATA
SHORTREF       SIMPLE		STARTTAG	SUBDOC	
SYSTEM	        TEMP		USELINK		USEMAP

включается следующей строчкой

NAMES SGMLREF

Можно переопределять зарезервированные имена (новые имена должны быть алфавитно-цифровые, возможно содержащие «.» или «-»):

NAMES SGMLREF
      DOCTYPE   DTD
      ELEMENT   EL
      PCDATA    TEXT

В этом примере, SGML-документы будут начинаться с «<!DTD», а не «<!DOCTYPE», декларации элементов — c «<!EL», а не «<!ELEMENT», а символьные данные — с «#TEXT», вместо rather «#PCDATA».

QUANTITYПравить

В этом разделе, схожим с #CAPACITY задаются (или переопределяются) численные величины-ограничения, на длины имен и литералов.

QUANTITY SGMLREF
         NAMELEN     32
         LITLEN    2048

В отличие от раздела #CAPACITY, если используется формула "QUANTITY SGMLREF", не требуется переопределять ни одну количественную величину. Если NAMELEN сделать меньшим 8, то необходимо переопределить все зарезервированные имена, чтобы уложиться в это ограничение.

FEATURESПравить

В этом разделе, должны быть перечислены все дополнительные SGML-свойства, причем обязательно в указанном порядке:

  FEATURES
     MINIMIZE DATATAG  NO  OMITTAG  NO   RANK     NO
              SHORTTAG NO
     LINK     SIMPLE   NO  IMPLICIT NO   EXPLICIT NO
     OTHER    CONCUR   NO  SUBDOC   NO   FORMAL   NO

Эти свойства деляться на три группы:

  • свойства минимизации
  • ссылочные свойства
  • иные

Для разрешения свойств

DATATAG
OMITTAG
RANK
SHORTTAG
IMPLICIT
FORMAL

нужно заменить «NO» на «YES».


Для разрешения свойств

SIMPLE
EXPLICIT
CONCUR
SUBDOC

нужно заменить «NO» на «YES» и число, означающее число одновременно разрешенных активных простых ссылок, активных явных ссылок, активных конкурирующих или вложенных документов соответственно.

APPINFOПравить

Информация из этого раздела не используется при разборе, но передается приложению, получающему результат работы SGML-парсера. Соответственно, команда может быть либо

  APPINFO NONE

либо задается какой-либо литерал:

  APPINFO "xyz"


По крайней мере часть этого текста взята с ресурса http://lib.custis.ru/ под лицензией GDFL.Список авторов доступен на этом ресурсе в статье под тем же названием.