#doctype

built-in shelf

Purpose

A built-in stream shelf that provides the name of the document element.

#doctype is attached as soon as OmniMark encounters the document element name at the start of the DTD, following the DOCTYPE keyword. Prior to this, #doctype is unattached. Specifically, it is never attached in the following contexts:

The #doctype is attached test can be used to determine whether the document element name is available.

The following example shows how to use the name of the document element to find an external entity when the external identifier at the head of the DTD has neither a public nor system identifier (for example, <!doctype doc system>). For example, if the file name of the DTD can be obtained by appending a .dtd suffix to the name of the document element, then

  external-text-entity #dtd unless entity is (system | public)
     output file (#doctype || ".dtd")
          

The #doctype shelf is normally set by the parser and is available only for reading, but you can modify its value in the following specific contexts:

Once a validating parser encounters the first element in the document instance, it will expect it to match the value of #doctype whether it was set by the parser or manually. A markup error will be issued otherwise. If #doctype is unattached or is open, a validating parser will throw a #program-error instead.

Setting the #doctype shelf is usually performed after #current-dtd is assigned. The following example function can be used to validate a well-formed XML instance against a compiled XML DTD without knowing the document element of the instance.

  define markup source function
     parse-xml-against-dtd (value xml-dtd       target-dtd,
                            value string source xml-document)
  as
     do scan xml-document
     match any ** lookahead "<" (letter [letter | digit | "-_.:"]*) => root-element
        do xml-parse document scan xml-document
           set #current-dtd to target-dtd
           set #doctype to root-element
           output #content
        done
     done