XML DOCTYPE Declaration

The DOCTYPE, or Document Type Declaration can contain a reference to a DTD document, and it may contain locally defined declarations.

The general syntax is:

<!DOCTYPERootElementPUBLIC "FPI" {"URI"} {[<!-- internal subset declarations -->] }>

or

<!DOCTYPERootElementSYSTEM {"URI"} [<!-- internal subset declarations -->]>

Meaning

  • RootElement—name of the top-level XML element
  • FPI—Formal Public Identifier
  • URI—name of external document containing external subset declarations (the DTD)

Description

The URI may refer to an external document with external subset declarations. The internal subset declarations are defined between the square brackets and may overrule any external declarations.

The declarations may describe the document structure by means of <!ELEMENT …> and <!ATTLIST…> declarations, and define character entity references using <!ENTITY …> declarations. The description of the document structure is often handled by a schema rather than the DTD, but character entity definitions are only declared in a DTD.

Note:  Uniface does not support internal subset declarations in the XML document itself for Uniface-compliant XML streams. For more information, see XML Streams.

DOCTYPE with External Declarations

The following DOCTYPE declaration references an external DTD using its public identifier:

<!DOCTYPE topic PUBLIC "-//Compuware//DTD Codex DITA Composite//EN" "codexDitabase.dtd">

DOCTYPE with Internal Declarations

The following DOCTYPE declaration defines the XML entities, elements, and attributes for a simple XML description of a film.

<!DOCTYPE movie SYSTEM "personal/movies/a" [
    <!ENTITY COM "Comedy">
    <!ENTITY SF "Science Fiction">

    <!ELEMENT movie (title+,genre,year)>
    <!ELEMENT title (#PCDATA)>
    <!ATTLIST title
           xml:lang NMTOKEN "EN"
           id ID #IMPLIED>
    <!ELEMENT genre (#PCDATA)>
    <!ELEMENT year (#PCDATA)>
    ]>

XML Structs

When converted without the /full switch, the DOCTYPE declaration is ignored.

When converted with the /full switch, the DOCTYPE declaration is converted to a Struct called RootElement, with annotation xmlClass set to doctype. Depending on the identifier (PUBLIC or SYSTEM), the xmlPublicID or xmlSystemID are also set.

Each local declaration is also converted to a Struct, and the xmlClass annotation is set to a value that corresponds to the XML declaration. as show in the following table. When converting from Struct to XML, DOCTYPE declarations are only generated if the xmlClass is set appropriately.

DTD Local Declarations to Struct
XML Construct Struct Conversion

Valid Annotation Tags

Element declaration:

<!ELEMENT …>

Named Struct with element name, and one nameless scalar member with the value. For more information, see XML Element Declaration. xmlClass = element-declaration
Internal entity declaration:

<!ENTITY …>

Named Struct with entity name, and one nameless scalar member with the value. xmlClass = entity-declaration
External entity declaration:

<!ENTITY …>

Named Struct with entity name, and no value. xmlClass = entity-declaration

xmlPublicID = Value

xmlSystemID = Value

Unparsed external entity declarations; these include the keyword NDATA followed by a name Named Struct with entity name, and no value. An additional annotation refers the entity to a Notation declaration. For more information, see XML Entity Declaration. xmlClass = entity-declaration

xmlPublicID = Value

xmlSystemID = Value

xmlNotation

Notation declaration:

<!NOTATIONnamePUBLIC "publicID""uri">

Named Struct with notation name and no value. xmlClass = notation-declaration

xmlPublicID = PublicID

xmlSystemID = URI

Attribute list declaration:

<!ATTLIST…>

Named Member Structs under the element name for which they are declared. For more information, see XML Attribute Declaration. xmlClass = attribute-declaration

xmlDataType = Type

xmlAttrMode = Mode

The root tag of the main XML document usually has the same name as the DOCTYPE, resulting in two Structs with the same name but different xmltype annotation and members. When addressing these elements, you need to ensure you have the correct one—the first for the Doctype or the second for the root element.

XML Struct: DOCTYPE with External Declarations

DOCTYPE declaration that references an external DTD using its public identifier:

<!DOCTYPE topic PUBLIC "-//Compuware//DTD Codex DITA Composite//EN" "codexDitabase.dtd">
<topic></topic>

When converted to a Struct using xmlToStruct/full, $dbgString contains the following:

[]
  [topic] = ""
    [$tags]
      [xmlClass] = doctype
      [xmlPublicID] = -//Compuware//DTD Codex DITA Composite//EN
      [xmlSystemID] = codexDitabase.dtd
  [topic] = ""
    [$tags]
      [xmlClass] = element

Note:  The result includes two topic Structs. You can address the one you want using the Struct index operator {n}:

vXmlClass = vStruct->topic{1}->$tags->xmlClass  ; Result: vXmlClass = "doctype"
vXmlClass = vStruct->topic{2}->$tags->xmlClass  ; Result: vXmlClass = "element"

If you omit the index number, both values are returned, with the values concatenated, which is usually not useful.

XML Struct: DOCTYPE with Local Declarations

XML document with DOCTYPE declaration that includes local declarations:

<!DOCTYPE movie SYSTEM "personal/movies/a" [
    <!ENTITY ACT "Action">
    <!ENTITY COM "Comedy">

    <!ELEMENT movie (title+,genre,year)>
    <!ELEMENT title (#PCDATA)>
    <!ATTLIST title
           xml:lang NMTOKEN "EN"
           id ID #IMPLIED>
    <!ELEMENT genre (#PCDATA)>
    <!ELEMENT year (#PCDATA)>
    ]>
<movie></movie>

After conversion with /full, string returned by $dbgString:

[]
  [movie]
    [$tags]
      [xmlClass] = doctype
      [xmlSystemID] = personal/movies/a
    [COM] = Comedy
      [$tags]
        [xmlClass] = entity-declaration
    [SF] = Science Fiction
      [$tags]
        [xmlClass] = entity-declaration
    [movie] = (title+,genre,year)
      [$tags]
        [xmlClass] = element-declaration
    [title]
      [$tags]
        [xmlClass] = element-declaration
      (#PCDATA)
      [xml:lang] = EN
        [$tags]
          [xmlClass] = attribute-declaration
          [xmlDataType] = NMTOKEN
      [id] = 
        [$tags]
          [xmlClass] = attribute-declaration
          [xmlDataType] = ID
          [xmlAttrMode] = #IMPLIED
    [genre] = (#PCDATA)
      [$tags]
        [xmlClass] = element-declaration
    [year] = (#PCDATA)
      [$tags]
        [xmlClass] = element-declaration
  [movie] = ""
    [$tags]
      [xmlClass] = element

Expressions for getting values from the Struct for the DTD:

vDocType = vStruct->movie{1}->$tags->xmlClass           ; Result: vDocType = "doctype"
vXmlEntityVal = vStruct->movie{1}->COM                  ; Result: vXmlEntityVal = "Comedy"
vXmlEntityTag = vStruct->movie{1}->COM->$tags->xmlClass ; Result: vXmlEntityTag = "entity-declaration"
vMember = vStruct->movie{1}->movie                      ; Result: vMember = "(title+,genre,year)"