SGML

Templating Reference

SGML Templating

SGML templating builds on SGML's NOTATION and LINK concepts (explained below) and allows parametric inclusion of other SGML files/resources (templates), such that entity references in templates are expanded into values provided from the invocation context.

Parameters can be provided either

  • from data attributes (attributes specified for data entities)

  • from content attributes (attributes specified on element in the main file which are expanded by templates)

  • from external resources such as SQL or SPARQL queries, web services, etc.

Link Processes

A link process, in SGML, is a general term for any kind of processing performed by code "linked" (as in dynamic link library) to a SGML parser library. The term "link process" as used in SGML has nothing to do with hyperlinks, and is better understood as a kind of stylesheet similar to a CSS stylesheet.

A link process declaration (LPD) is a declaration set (a syntactical construct that can appear in a document prolog along with a DTD) declaring properties for link processes and their values. These properties are declared as link attributes, re-using standard attribute list declaration syntax.

Link attributes are associated with content elements in the same way as plain content attributes, but aren't serialized to output. Values for link attributes are determined either by #FIXED default values declared for the respective attribute in ATTLIST declarations in the link process declaration, or can be determined in a state-dependent way based on link sets declared in the link process declaration.

A link set is a rule that associates link attribute values to a particular element appearing in the content, potentially with filtering rules that further restrict the elements to which the rule(s) apply. Link attributes determined via link sets, unlike link attributes merely defaulted by a #FIXED link atttribute declaration, can be given values depending on where the element to apply to appears within content.

For example, link sets can specify that list items with odd ordinal numbers should be rendered differently from those with even ordinals. This is achieved by using two link sets, each associating different link attribute values to the same list item content element, and by telling the processor to use the other link set as applicable link set ("current link set") once a link attribute has been determined.

Link attributes are not included in the output document of SGML processing; instead, in sgmljs.net, link attributes determine templates and template parameters to apply on the respective elements to which the link attribute is assigned by link processing, and the SGML processing output for those elements is determined by the template (note there are additional ways for a template to influence output, such as via result elements on explicit link rules that don't select a template, and via entity preemption; these are explained in detail further down).

While implicit link processes are restricted to associate link attributes to content attribute as described, explict link processes can be used to produce entirely new SGML documents driven by source elements. Explicit link processes will only produce result elements if explictly told to do through link rules, but, unlike implicit link don't copy source markup to result markup, hence can filter (omit) source content which implicit link by themselves can't do.

Link processes can be chained to form a pipeline of link processes where the output of one link process serves as the source content for the next chained link process (subject to the restrictions explained below). In this way, link processing can perform fairly rich document preparation and extraction tasks such as generating an outline for navigation, perform paging, format search results, add boilerplate content, etc.

Apart from implicit and explicit link processes, SGML also offers simple processes. A simple link process contains global properties of a link process, rather than properties of individual elements; syntactically, a simple link process is declared as a special kind of implicit link process where link attributes are only declared on the document element (the root element of the document).

For a LPD to be processed and have any effect, it must be active. A link process is activated by supplying its name as an invocation parameter to the active_lpds command-line parameter in command-line processing. In web templating, link processes having the name web and http are activated by default, if present in a document to serve.

Implicit LPDs

An implicit LPD has the following form

<!LINKTYPE lpd-name dtd-name #IMPLIED [
          [entity-declarations]
          link-attribute-declarations
          <!LINK #INITIAL link-rule [link-rule] ...>
         [<!LINK link-name link-rule [link-rule] ...>
          <!LINK link-name link-rule [link-rule] ...> ...]
]>

where link-rule is an item of the form

element [#POSTLINK target] [#USELINK target] [ attr=value ... ]

or

(element1|element2|...) [#POSTLINK target] [#USELINK target] [ attr=value ... ]

Note that in this syntax description for a link rule the square braces around attribute specifications are verbatim SGML code text.

#POSTLINK and #USELINK targets and attribute specifications are optional.

lpd-name

is the name of the link process to declare; the name must be distinct from every other declaration set name (LPD or DTD) in the document

dtd-name

is the declaration set name of the DTD containing the elements on which link attributes are being declared

entity-declarations (optional)

is one or more (general, parameter, or data) entity declaration; see entity preemption

An (implicit or explicit, but not simple) link process declaration must include a single #INITIAL link set declaration, and can optionally contain additional named link set declarations

Link attributes don't get output as content attributes, but are used to associate processing properties with source elements; in particular, if a link process assigns a template to a link attribute, then the respective element on which the template is assigned is replaced by the template content for output, possibly with further link attributes as template parameters.

Otherwise, an implicit link produces its input sequence of elements and other markup constructs to the output markup unchanged. But note that, like for all link processes, Entity Preemption can also influence the output of an implicit link process.

For example, the following (simplified HTML) document contains an LPD that will assign "body value" to the html content element, and "p value" to the p content element:

<!doctype html [
	<!element html (head?,body)>
	<!element body (p*)>
]>
<!linktype l [
	<!attlist (html|p) linkattribute cdata #implied>
	<!link #initial html #uselink inbody [ linkattribute="body value" ]>
	<!link #inbody p [ linkattribute="p value" ]>
]>
<html>
	<body>
		<p>Hello</p>
	</body>
</html>

Starting in the #INITIAL link set (where "body value" is determined as link attribute), the #USELINK rule takes the link processor to the inbody link set, where "p value" is determined as link attribute on the p element.

Note that #USELINK is pointless here, and only used for demonstrating the syntax and general operation of implicit link processing; in the example, the rule for p could have as well been included in the #INITIAL link set with the same result.

Explicit LPDs

An explicit LPD declares a link process that transforms source markup declared in a source DTD to result markup declared in result DTD. The result DTD can be the same as the source DTD, or can be different.

If it is different and multiple DTDs are involved in an explicit link process, the SGML prolog contains multiple DTDs such as in the following example:

<!doctype A [
	...
]>
<!doctype B [
	...
]>
<!linktype atob A B [
	...
]>

In the example, the declaration for the explicit LPD atob specifies that it transforms source markup declared in declaration set A to result markup declared in declaration set B.

If an explicit LPD's source and result DTD is the same, no additional DTD for the result markup needs to be declared in the document prolog, and the declaration of the explicit LPD takes the following form:

<!linktype name A A [
	...
]>

ie. source and result declaration set name are the same in the link process declaration.

Like an implicit LPD, link attributes are used to associate processing properties with source elements; in particular, if a link process assigns a template to a link attribute, then the respective element on which the template is assigned is replaced by the template content for output, possibly with further link attributes as template parameters. If on the other hand the source element is matched by a link rule, but no template is determined for the source element, then the content is replaced by the matching link rule's result element and result attribute specification.

Note that if a template is assigned, the result attributes for the element specified in the link rule, if any, are ignored, and any output is determined by the template instead.

An explicit LPD performs tag inference and validation of its produced result markup against the result DTD, just as if the result markup were parsed, rather than generated.

Note that other SGML processing systems might not perform inference and validation on the result markup of an explicit LPD.

The syntax of an explicit LPD is very similar to that for implicit LPDs, except that a source and result declaration set must be specified (instead of just a declaration set and #IMPLIED, as in implicit LPDs), and that a link rule maps a source to a target element specification, rather than containing just a single element and link attribute specification as in implicit LPDs):

<!LINKTYPE lpd-name source-dtd-name result-dtd-name [
          [entity-declarations]
          link-attribute-declarations
          <!LINK #INITIAL link-rule [link-rule] ...>
         [<!LINK link-name link-rule [link-rule] ...>
          <!LINK link-name link-rule [link-rule] ...> ...]
]>

where link rule is an item of the form

element [#POSTLINK target] [#USELINK target] [ attr=value ... ]
	result-element [ result-attr=value ... ]

or

(element1|element2|...) [#POSTLINK target] [#USELINK target] [ attr=value ... ]
	result-element [ result-attr=value ... ]
lpd-name

is the name of the link process to declare; the name must be distinct from every other declaration set name (LPD or DTD) in the document

source-dtd-name

is the declaration set name of the DTD containing the elements which appear as source elements in link rules, and on which link attributes are being declared

result-dtd-name

is the declaration set name of the DTD containing the elements which appear as result elements in link rules, and which will be produced from link rule applications

entity-declarations (optional)

is one or more (general, parameter, or data) entity declaration; see entity preemption

element (and element1, element2)

is the name of an element in the source-dtd-name declaration set, which will be matched against a source content element

result-element

is the name of an element in the result-dtd-name declaration set which will be produced as result element for every matching (source) element; the result attributes and child content for the produced element are determined either by a template, if a template is implied by the link attributes on the link rule, or, if no template is implied by the link attributes, by the result attributes, if any, specified on the link rule

result-attr

is an result attribute to produce unless a template is applied to produce the result element's attributes and child content

Unlike an implicit link process, an explicit link process only produces result elements to it's output for those source elements which have matching context-dependent link rules applied; if the current link set in an explicit link process hasn't a matching rule for the source content at the context position, no result element is produced.

When no element of a source document can be matched at all by link rules, an explicit link process produces a document containing just an empty result document element, having the result document type name as element name.

A link rule in an explicit link set can also use the special token #IMPLIED instead of either the source or result element (but not both); see link rules with #IMPLIED source element and link rules with #IMPLIED result element.

Explicit Link rules having the form

#IMPLIED [#POSTLINK target] [#USELINK target] [ attr=value ... ]
	result-element [ result-attr=value ... ]

(using #IMPLIED as source element) will create an additional element with the respective result element name and result attributes when it is in the current link set, and any start-element event is encountered.

A link rule having #IMPLIED as its source element must be the only link rule in it's containing named link set, and must have a #USELINK target declared.

Contained in a named link set, it is only reached from a preceding sibling or parent element's link rule application transitioning to it by referencing it in its #USELINK or #POSTLINK target.

Once the result element for a rule is produced, the link state immediately transitions to the link set referenced in its #USELINK target. If the transitioned-to link set, in turn, contains a link rule having #IMPLIED as its source element, then the result element of that link rule is also produced to the output, and so on, until a link set is reached which doesn't contain a link rule that has #IMPLIED as its source element.

In this way, rules with #IMPLIED source elements can be used to produce arbitrary many nested elements.

It's an error if, when transitioning to a #USELINK target of a link set having a rule with #IMPLIED source element, the transitioned-to target has already been transitioned to before in the chain of followed #USELINK targets; ie. the chain of #USELINK targets traversed must not form a cycle.

Explicit Link rules having the following form

element [#POSTLINK target] [#USELINK target] [ attr=value ... ] #IMPLIED

or

(element1|element2|...) [#POSTLINK target] [#USELINK target] [ attr=value ... ] #IMPLIED

(using #IMPLIED as result element) will produce the source element as result element, if it is allowed to occur directly at the context position in the result document according to the result DTD. Unlike with regular result elements, tag inference is not performed. If the element is not allowed to occur at the context position (or if the element isn't allowed to occur anywhere) in the result markup, it is silently ignored and not produced to the output.

If the result element is produced to the output, any source attributes allowed to occur in the result element are copied over from the source element to the result element, too. To assess if a source attribute is allowed to occur in the result element, the link processor considers only the name but not the declared value of the attribute. It's an error if, when a link rule with an implied result element matches, an attribute is specified or implied in content, and an attribute with the same name is declared in the result DTD, and the value specified or implied for the content attribute isn't a valid attribute value for the result attribute (for example, if the result element declares an attribute with declared value NUMBER, and the corresponding source attribute with the same name is declared CDATA and doesn't contain a string that can be parsed as NUMBER).

A result element is allowed to occur in the result markup according to the standard rules for tag validation; ie. if either

  • it is accepted as regular content token at the result context position, or

  • it is accepted as an included element at the result context position, or

  • the result context position has declared content ANY, and the element isn't in the set of excluded elements at the result context position, or

  • the result context position refers to an implied-ANY element (ie. an element not declared in the result DTD, and treated as if it were declared ANY because IMPLYDEF ELEMENT YES is specified or implied in/by the SGML declaration)

Simple LPDs

Simple LPDs contain only a single link attribute declaration and/or entity declarations:

<!LINKTYPE lpd-name #SIMPLE #IMPLIED [
          [entity-declarations]
          [link-attribute-declaration]
]>

(having SIMPLE #IMPLIED in place of the source and result DTD name, respectively),

Link attributes must be declared on the document element (the root element) of the base DTD (the first DTD) in the containing document. Template notations in simple LPDs aren't supported; instead, simple LPDs are used to provide document-wide properties in a simple item-value format to auxiliary purposes such as e.g. HTTP delivery parameters.

Simple links can also be used for entity preemption.

The prolog of an SGML file can contain multiple document type declarations and link process declarations. More than a single explicit link process (or none at all) can be active at any point in time. If multiple link processes are active, the result markup of a link process is used as input markup to another link process, in turn, such that multiple active link processes can form a pipelie of link processes, with the ultimate result markup that of the link process placed last in the chain. To form a pipeline, the result document type of the first link process must match the source document type of the second. However, only a single implicit link process can be active at any point in time. If one or more explicit link processes are active, a single implicit link process can be active in addition; the single active implicit link process, if any, is always the last link process in a pipeline of possibly more than a single link process.

Activation of a link process can be requested from the SGML processor by supplying the name(s) of link processes to activate (provided the name list meets the above criteria). Practically, when invoked via the command line, a command line argument is supplied listing the link process(es) to activate.

Alternatively, the SGML processor can be told to determine a link pipeline based on a requested target document type name. When the SGML processor is told to produce a given target document type name, it considers the base document type and the explicit link processes declared in the document to arrive at a pipeline of one or more link processes to activate that produces the requested target document type name.

For example, the prolog of the following document declares the lnk1, lnk2, and lnk3 link processes, along with document type names for the base document type and the document types produced as intermediate results of the link processes:

<!DOCTYPE doc [
	<!ELEMENT doc - - (#PCDATA)>
]>
<!DOCTYPE out [
	<!ELEMENT out - - (#PCDATA)>
]>
<!DOCTYPE out2 [
	<!ELEMENT out2 - - (#PCDATA)>
]>
<!DOCTYPE out3 [
	<!ELEMENT out3 - - (#PCDATA)>
]>
<!LINKTYPE lnk1 doc out [
	<!- ... -->
	<!LINK #INITIAL doc out>
]>
<!LINKTYPE lnk2 out out2 [
	<!- ... -->
	<!LINK #INITIAL out out2>
]>
<!LINKTYPE lnk3 out2 out3 [
	<!- ... -->
	<!LINK #INITIAL out2 out3>
]>
<doc>Text</doc>

When the SGML processor is instructed to produce markup with the out3 target document type name, it will activate the lnk1, lnk2, and lnk3 link process resulting in out3 markup as ultimate result markup.

Note the ability to activate a particular number of link processes, such as 3 in this case, is determined by the processors hard limit of supported simultaneous link processes.

Entity preemption

As an additional feature of LPDs, any LPD (including simple LPDs) can declare entities. Entities declared in a LPD override ("preempt") those declared in the document's DTD having the same name (but LPDs can also contain private entities that don't preempt DTD entities).

For example, the following document contains a very basic simple LPD in addition to a DTD:

<!doctype html [
	<!entity visitor-name "Unknown">
]>
<!linktype myformat #simple #implied [
	<!entity visitor-name "Chef">
]>
<html>
<body>
<p>Hello, &visitor-name</p>
</body>
</html>

The effective value of the visitor-name entity is Chef, when the myformat LPD is active.

More generally, the effective value for a given entity is declared by the entity declaration that gets processed first. When processing a document, SGML first processes all active LPDs, in the order they appear in the document prolog; then SGML processes the base (first) DTD. SGML performs these steps in a separate pass before considering other markup declarations. Therefore, a link declaration set may reference parameter entities declared in a DTD, or in an active link set declaration preceding it in the document prolog. Moreover, a DTD can reference parameter entities declared in an active link declaration set.

As a special rule, sgmljs.net tolerates parameter entity references in marked section keywords in link declaration sets without a prior declaration as of the order described above. The replacement text of those (yet) unresolved parameter entities is considered the empty string until a declaration is established (in the described order). Moreover, while marked sections with an empty keyword are treated as if INCLUDE were used as keyword, marked sections within link process declarations are treated as if IGNORE were used as keyboard.

This feature can be used to obtain replacement text for parameter entity references from a DTD, without having to declare (and thus preempt) those in a LPD.

For example, in the following document, when the L link process is active, the replacement text for %e (and thus e) will be from DTD, because the replacement text for the include-ignore parameter entity is only established in the DTD, thus will be treated as IGNORE in the marked section within the link declaration set:

<!DOCTYPE D [
	<!ELEMENT D - - (#PCDATA)>
	<!ENTITY % include-ignore "INCLUDE">
	<!ENTITY % e "from DTD">
	<!ENTITY e "%e">
]>
<!LINKTYPE L #SIMPLE #IMPLIED [
	<![ %include-ignore [
		<!ENTITY % e "from LPD">
	]]>
	<!ATTLIST D a CDATA #FIXED "a">
]>
<D>&e</D>

There's a special portability idiom to achieve the same result using third-party SGML software (SP/OpenSP) which treat entity preemption slightly different:

<!DOCTYPE D [
	<!ELEMENT D - - (#PCDATA)>
	<!ENTITY % include-ignore "INCLUDE">
	<!ENTITY % e "from DTD">
	<!ENTITY e "%e">
]>
<!LINKTYPE L #SIMPLE #IMPLIED [
	<![ %include-ignore [
		<!ENTITY % include-ignore "IGNORE">
		<![ %include-ignore [
			<!ENTITY % e "from LPD">
		]]>
	]]>
	<!ATTLIST D a CDATA #FIXED "a">
]>
<D>&e</D>

Implicit and explicit LPDs can contain a single IDLINK link set declared as follows

<!IDLINK link-rule [link-rule] ...>

where link rule is an item of the form

id element [#POSTLINK target] [#USELINK target] [ attr=value ... ]

(for implicit LPDs), or

id element [#POSTLINK target] [#USELINK target] [ attr=value ... ]
	result-element [ result-attr=value ... ]

(for explicit LPDs).

Link rules in IDLINK sets are matched on elements of the respective type when the element has an ID attribute declared in the DTD, and the ID value specified on the element matches the id declared in the link rule.

Elements matching a link rule in the IDLINK link set have their link and result attributes always determined by the matching link rule in the IDLINK link set in preference to any matching link rules in the current link set.

At any point in time when processing a SGML document, a link process has a current link set; the initial current link set at the start of the document is the #INITIAL link set.

When processing an element, the link process inspects the current link set to check if it contains one or more link rules for the element being processed, ie. if the name of the element to process occurs as the element (or as one of the elements in the name group) of a link rule. If so, it proceeds with link rule selection and link attribute determination as described below.

Otherwise, if an element isn't matched by any link rule in the current link set, no link attributes are inferred for that element.

Note that the SGML standard describes a fallback mechanism where link attributes are determined by a parent or predecessor link set, but neither sgmljs.net nor other SGML software implements this behaviour.

Once a link processor has established that a link set contains link rules for the element being processed, it determines the specific link rule (of potentially multiple link rules) to apply as follows:

  • if the current link set has a single link rule for the element to process, then that single link is selected

  • if it has multiple link rules for the element to process (ie. if the element to process appears as element or in the name group of more than one link rule), the link attribute specifications of the applicable link rules are checked to select a single rule; if any link rule specifies a link attribute with the same name as a content attribute on the respective element, and the content attribute value for the current element has the same value as specified in the link rule, then the first such rule, in the order specified in the link set, is selected; as a special rule, a content attribute that is declared, but not specified in content, matches a link attribute rule specifying an empty string literal value for that attribute

To ensure that a single link rule can always be selected by the above algorithm, sgmljs.net performs the following checks, depending on "strict" or "non-strict" (the default) processing mode.

In strict mode, sgmljs.net checks that any link rule specifying a link attribute having the same name as a DTD attribute is part of a set of multiple rules for the respective element in the link set, and that for any link set with multiple link rules for the same element,

  • each link rule, of the multiple link rules applying to the same element, has one or more link attributes specified (as required by standard SGML syntax), and, moreover,

  • each link rule, of the multiple link rules applying to the same element except the last, specifies at least one attribute that has the same name as a content attribute declared on the respective element in the DTD, and

  • the last link rule (in the order appearing in the link set) doesn't have link attributes specified that have the same name as a DTD attribute.

In non-strict mode, sgmljs.net checks that

  • each link rule, up to the last, of mutliple link rules applying to the same element, has one or more link attributes specified,

  • like above, each link rule, of the multiple link rules applying to the same element except the last, specifies at least one attribute that has the same name as a content attribute declared on the respective element in the DTD, and

  • the last link rule doesn't have link attributes specified at all.

Link attribute value(s) specified in the selected rule, if any, are implied as link attribute values(s) for the element being processed.

If no value for a link attribute (ie. of those declared as attributes for the element in the LPD) is specified in the link rule, then the attribute default declared in the attribute declaration in the LPD, if any, is implied as value for that link attribute.

If the selected link rule contains a #POSTLINK clause, the target link set name of the #POSTLINK clause is set as the current link set for any elements after the end-element event of the current element has been processed; ie. the #POSTLINK target applies to immediately following sibling elements, and their descendant elements (until another #USELINK or #POSTLINK target is set as the current element). On the end-element event for the parent element of the current element, the current link set is reset to that of the parent element, or the parent element's #POSTLINK target, if it has one.

If the selected link rule contains a #USELINK clause, the target link set name of the #USELINK clause is set as the current link set for any child element of the current element; otherwise, the current link set name isn't changed for child element content.

A #USELINK or #POSTLINK target may specify #EMPTY in place of a link set name, in which case no output markup events are generated for child content or following-sibling content, respectively, of the element being processed.

When #EMPTY is the current link set, neither start-element events nor character data events are produced to the output; otherwise, character data is delivered to the output provided it is accepted at the output context position, even when the containing element wasn't covered by a link rule in an explicit link process, and hence didn't produce a result markup element.

In sgmljs.net SGML, consistent with the SGML standard, a #USELINK or #POSTLINK target must not specify #INITIAL in place of a link set name. Other SGML systems might support #INITIAL in place of a named link set, in which case the current link set of the child content, or following-sibling content, respectively, is set to the #INITIAL link set containing the link rules effective at the document element of the document being processed.

Determining and applying a notation

A link attribute having NOTATION declared value, when determined to have a value in the link attribute determination step described anove, can specify special processing. In sgmljs.net SGML, when a NOTATION declared link attribute is assigned the name of a notation having the SGML public identifier, then the assigned notation's system identifier is used as a template notation.

Data attributes for elements (DAFE)

When the assigned notation has data attributes with the same name as link attributes declared on the element on which the notation is assigned as template, then the link attribute values are supplied as the respective data attributes for the notation/template application. Moreover, the processor passes child content of the element on which templating is invoked to the template processing context.

The DAFE feature allowing data attributes to have their values populated by content or link attributes is part of ISO/IEC 10744 (HyTime 2nd ed.).

See the next chapter for template processing details.

sgmljs.net SGML applies an additional feature of DAFE (also as specified by ISO/IEC 10744):

If a notation is applied in a link process, the special NotNames link attribute is evaluated, and is expected to specify space-separated pairs of attribute names where the respective first attribute name is the name of a data attribute for the notation applied, and the second is the name of a link attribute which should serve as the source attribute for that data attribute (eg. in this capacity, NotNames can populate data attributes from link attributes with different names). Note, however, sgmljs.net SGML does not support general aliasing and renaming attributes for use as data attributes. Only the two following special values for NotNames are supported:

`#NOTCONT <attribute>`

and

`<attribute> #CONTENT`

If the token #NOTCONT is used in place of the first attribute, then sgmljs.net SGML populates the notational content from the specified attribute name.

If the token #CONTENT is used in place of the second attribute, then sgmljs.net SGML populates the specified attribute with the element text content of the context element where it is applied.

As an example for the former, the following declares a notation and arranges for the content data attribute to be provided as notational content:

<!NOTATION nt ...>
<!ATTLIST #NOTATION nt
	content CDATA #IMPLIED
	NotNames CDATA #FIXED "#NOTCONT content">

Templates

This chapter introduces SGML templates. SGML templates provide a more advanced technique of transcluding content from foreign documents or other resources (in addition to plain parsed references) with support for supplying template parameters from the document where the template is transcluded.

SGML templates do not introduce new SGML syntax, but makes use of SGML notations and other SGML constructs.

Any plain SGML document can be used as SGML template. A template SGML document typically (but not necessarily) will use system-specific entities in uppercase letters to refer to values obtained from the environment/document where the template is transcluded.

For example, the following hypothetical SGML document, greeting.sgm can be used as a template receiving the guest-name and number-of-new-messages parameters (using #CONREF entity expansion as explained above):

<!doctype div system [
  <!entity GUEST-NAME system>
  <!entity NUMBER-OF-NEW-MESSAGES system>
]>
<div>Hello, &GUEST-NAME. You have &NUMBER-OF-NEW-MESSAGES new messages</div>

A document, master.sgm, making use of the above template can look like this

<!doctype html [
  <!attlist div template entity #conref>
  <!entity msg "placeholder message">
]>
<!linktype web #simple #implied [
  <!notation sgml
    public "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
  <!entity msg system "greeting.sgm" ndata sgml [ guest-name="Max" number-of-new-messages=3 ]>
]>
<html>
  <body>
    <div template=msg>
  </body>
</html>

The SGML processor, when processing the master.sgm file with the web link process activated (and when told to output HTML), will produce the following output:

<!doctype html>
<html>
  <body>
    <div>Hello, Max. You have 3 new messages</div>
  </body>
</html>

Using an SGML template as an entity

In the example shown the SGML processor performs the following steps to produce the output (making use of #CONREF entity peemption):

  • the DTD for the file being processed, master.sgm, declares a content reference (#CONREF) attribute with ENTITY declared value for the template attribute on the div element; this tells the processor to treat div elements as EMPTY when the template attribute is used

  • the declaration for the msg entity in the LPD preempts (overrides) the declaration in the DTD so the dummy declaration for msg in the DTD gets ignored; the msg entity is declared in the LPD as an entity in the sgml notation, which, in turn, by reference to the SGML public identifier ISO//..., indicates to the processor to handle the notation as SGML template

  • the processor, when encountering the div attribute, will start an SGML processing sub-context using msg's system identifier greeting.sgm as file to process; the guest-name and number-of-new-messages processing parameters, supplied via data attribute on the msg entity declaration, are declared as the GUEST-NAME and NUMBER-OF-NEW-MESSAGES system-specific entities, respectively, in the template's DTD, for reference from template content

Note that GUEST-NAME and NUMBER-OF-NEW-MESSAGES must be uppercase; this is because SGML's default settings SYNTAX NAMECASE GENERAL YES and SYNTAX NAMECASE ENTITY NO treat attribute names (and element, notation names, and name tokens in enumerated attributes) as if an uppercase value had been specified even if a lowercase or mixed-case spelling had been used, whereas for entity names no case-folding is applied (they're treated as-is and eg. ent is a different entity than ENT). Since templating exposes attributes of a master document as system-specific entities in a template document, unless settings for SYNTAX NAMECASE GENERAL and SYNTAX NAMECASE ENTITY are set explicitly to match, the template will receive system-specific entities in uppercase (case-normalized) form. Hencee, it is recommended to always use template parameters in all-uppercase spelling which avoids any problems.

Note case-folding of attributes (and elements and notations etc.) is not visibile when outputting HTML (the default), as HTML serializiation will always output the lowercase form for names (the preferred form for HTML), even if internally any name is case-folded to the uppercase form.

Using a SGML template as a notation

The same template as in the previous example, greeting.sgm, can alternatively be invoked as a template notation (instead of as an entity as shown in master.sgm) like this:

<!doctype html [
  <!-- can be left empty -->
]>
<!linktype web html #implied [
  <!notation sgml
    public "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
    "greeting.msg">
  <!attlist #notation sgml
    guest-name cdata #implied
    number-of-new-messages cdata #implied>
  <!attlist div
    n notation (sgml) #fixed sgml
    guest-name cdata #fixed "Max"
    number-of-new-messages cdata #fixed "3">
]>
<html>
  <body>
    <div guest-name="Max" number-of-new-messages="3"></div>
  </body>
</html>

The SGML processor will process the document as follows, producing the same output as in the previous example:

  • the processor handles notations declared by reference to the SGML public identifier as template notation and uses the system identifier greeting.sgm of the template notation as template file name; moreover, template parameters are represented as data attributes declared on the template notation

  • the LPD assigns the sgml notation to the n link attribute, informing the processor that it should apply the greeting.msg template on every div element

  • the LPD also assigns the guest-name and number-of-messages link attribute with the #FIXED values from the link attribute declarations

  • the processor extracts data attributes as template parameters from link attributes having the same name as data attributes; ie. the template parameter guest-name is populated from the link attribute guest-name

Alternatively, and more usefully, template parameters can be extracted from content attributes as follows:

<!doctype html [
  <!attlist div
    guest-name cdata #implied
    number-of-new-messages cdata #implied>
]>
<!linktype web html #implied [
  <!notation sgml
    public "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN"
        "greeting.sgm">
  <!attlist #notation sgml
    guest-name cdata #implied
    number-of-new-messages cdata #implied>
  <!attlist div
    n notation (sgml) #fixed sgml
    guest-name cdata #implied
    number-of-new-messages cdata #implied>
]>
<html>
  <body>
    <div guest-name="Max" number-of-new-messages="3"></div>
  </body>
</html>

As an extension of the example before, in particular, the document body may contain multiple div elements with different attributes, which will result in multiple template applications to be produced to the output. For example,

...
<html>
  <body>
    <div guest-name="Max" number-of-new-messages="3"></div>
    <div guest-name="Maria" number-of-new-messages="5"></div>
  </body>
</html

will produce

...
<html>
  <body>
    <div>Hello, Max. You have 3 new messages</div>
    <div>Hello, Maria. You have 5 new messages</div>
  </body>
</html

So that the SGML processor can supply a template parameter from a content attribute,

  • the content attribute (DTD attribute) must be declared on the element on which the template is applied, and

  • a data attribute having the same name as the content attribute must be declared on the template notation,

and (as already shown in the notation examples before)

  • a NOTATION link attribute must be declared on the element, and assigned a notation that is declared using the SGML public identifier, or a notation that derives from a notation using the SGML public identifier (see below)

  • the template notation must declare a system identifier for locating the template.

Declaring template notations

As shown in the example before, sgmljs.net recognizes those notations as templates notations that are declared with the SGML public identifier

ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN

When declaring more than one template notation, multiple notation names and declarations must be used so that the system identifiers containing the file names for each template can contain paths to the different locations of the respective template notations, and so that different sets of data attributes can be declared as required.

There is an alternative to declaring the SGML public identifier directly on a notation for it to be treated as template notation:

<!notation sgml
  public "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
<!notation mytemplate system "my-template.sgm">
<!attlist #notation mytemplate superdcn name #fixed sgml>

This declares the sgml notation by just using the SGML public identifier, ie. omitting the system identifier, then declares a template notation, mytemplate, in a separate declaration. The mytemplate notation is recognized by sgmljs.net as a SGML template notation because it has the superdcn attribute declared, and the value of the superdcn atttribute is set (as #FIXED value) to the name of a notation declared with the SGML public identifier.

Capturing and supplying child content as template parameter

When using a template notation in content, as shown in the example where the template extracts content attributes, a template notation can also receive child content of the element on which the template is invoked. The template receives child content of the master context via it's standard input, and can access it using the <osfd>0 system identifier.

For example, when using the following fragment in the same context as above

<div guest-name="Max" number-of-new-messages="3">
  <p><h3>Message 1</h3><p>Bla bla blah ... </p>
  <p><h3>Message 2</h3><p>...</p>
  <p><h3>Message 3</h3><p>...</p>
</div>

the following template references the child content of the div element from the master context via the content entity as follows (adding a h2 before it):

<!doctype #implied system [
  <!entity content system "<osfd>0">
  <!entity guest-name system>
  <!entity number-of-new-messages system>
]>
<div>Hello, &guest-name. You have &number-of-new-messages new messages</div>
  <h2>Details</h2>
  &content
</div>

Nested templates

Since child content of elements on which templates are implied are captured as notational content for supply to subsequent processing pipeline stages, link rules descending from a state where a template is applied, as transitioned-to via #USELINK targets from a link rule that implies a template, are not reached. Once a template is applied, no further link state propagation is performed on child content of the element on which the template is applied within the invoking link process. Link rules implying templates are effectively treated as though they were declared with #USELINK #EMPTY.

Processing templates

Output of a template application is produced in a separate SGML processing context invocation on the template notation or entity as main file, and such that each data attribute declared and supplied in the master context can be accessed as a system-specific general or parameter entity.

Child content of the element on which the template is applied is captured in the master context as the sequence of normalized markup events (generated according to the master context's parsing rules declared in markup and SGML declarations), and is serialized to a character stream which is supplied to the template via <osfd>0.

A template produces an element with the same name as that on which the template is applied. Moreover, generated template child content must be valid in the master context into which it is included.

The master context supplies the element on which a template is applied as the target document type name to the template processing sub-context (see Multiple link processes).

The sub-context will then either

  • parse the template document with respect to its base document type, if the base document type name matches the requested target document type name, or if the base document type name is #IMPLIED, or

  • otherwise, determine a link pipeline from the link processes declared in the template document, and from those supplied as implied link processes from the master context, (see Use of templates in multi-stage processing pipelines) such that the result document element of the link pipeline matches the requested target document type name (eg. the element on which the template is applied in the master processing context)

Strict templates

The SGML processor enforces this by requiring that the template uses <!DOCTYPE ... SYSTEM .. as DTD, ie. the template must include the markup declarations of the master context by referencing a system-specific external subset that the master context sets up for the template context.

The template may declare its DTD either using

  • <!DOCTYPE element SYSTEM ..., where element is the element on which the template is applied, or

  • <!DOCTYPE #IMPLIED SYSTEM ..., which makes the template processing context determine the document element from the first content element in the template document (which must be the element on which the template is applied)

By the resolution rules for system-specific entities, the template processing context picks up the prescribed markup declarations that the master context has created via a file name generated from the template document element.

For example, if the template document element is div, the template processing context accesses the external subset by reading the file div.dtd. The file is looked up in a directory that the master context created and supplied for the template invocation, and in which it has placed the div.dtd file containing markup declarations that the template are parsed with and that the template has to conform to.

As a consequence, if the template doesn't use the expected element for its document element (the element name on which the template is applied), it will fail to locate the file for the external subset in the directory provided by the invoking master context.

Markup declarations received by a template processing context from an invoking master context don't contain entity declarations, short reference map declarations, and short reference use declarations. Moreover, parameter entity reference in the received declaration set are pre-expanded into the replacement values used by the master context.

The following restrictions apply to documents included as strict templates:

  • documents included as strict templates cannot declare and/or use data entities; normally, data entity references (other than for CDATA data entities) are serialized as-is (as reference, rather than as expanded text) to the output, but a template's data entities aren't declared in the master's DTD, nor are the data entities declared in a master's DTD visible to the template so references to data entities are rejected in template content

  • documents included as strict templates cannot use referential attributes (those with #CURRENT default, or with ID, IDREF, IDREFS, ENTITY, ENTITIES, or NOTATION declared value) because these interfere with the master's context such that invalid markup could be produced

  • an element on which a strict template is applied must have declared exclusion exceptions that are at least as strict as those effective on the element in the master context where the template is applied, if any; that is, the exclusion exceptions declared in the master context's DTD on the element on which a strict template is applied must exclude all elements which are contextually excluded at the position where the template is applied in the invoking master context (ie. not only on the element directly but also on it's parent elements)

  • documents included as strict template shouldn't use element declarations; declaring and using new elements from within a template will produce invalid markup if the master context hasn't the IMPLYDEF ELEMENT YES feature; note the master context is expected to enforce this by declaring e.g. a content model on the element on which the template is applied (rather than allowing ANY content on it); by declaring a content model on the template element, template processing can't place elements that are undeclared in the master as template child content; note that template processing itself (when not constrained by the master DTD) does not enforce that no element is used which is declared in the template and this enforcement must be expressed by the master DTD

  • documents included as strict templates don't apply short reference replacement, unless short reference map and short reference use declarations are present in the internal subset or other explicit declarations in the strict template.

Note documents included as strict template can (by default) declare and introduce new attributes, since the IMLYDEF ATTLIST YES feature is set by default, and output serialization will always produce a normalized attribute specification output (such that e.g. short forms of attribute specification in a template are always serialized in canonical form to the output, irrespective of what short forms are supported in the master context output).

Lax templates

In "lax" templates, the template doesn't have to declare it's DTD using <!DOCTYPE ... SYSTEM ..., but must use an external subset with the same system identifier as the external subset that the invoking master context uses.

The template accesses any markup declarations that it shares with the invoking master context via regular processing of markup declarations in the shared external subset. Parameter entity reference in the external subset are not pre-expanded, but are expanded in the template processing context. Note this means that expanded values for parameter entities in the template processing context could be different from those of the master processing context.

Lax templates, in general, aren't guaranteed to produce content that is valid according to the DTD of the invoking master process; instead, this must be ensured by proper DTD and/or template authoring.

Exceptions use case

A driving use case for lax templates is to propagate context-sensitive exclusion exceptions into template processing contexts. In order to make use of this, the used DTD must play along (have a placeholder where exceptions are to be inserted), and we need a way to materialize, into a data attribute, the exclusions effective at a given template expansion place.

The intent of the following hypothetical markup declarations is to allow <script> anywhere inside <sub> except when descending from <usercontent>. The template is invoked on <sub>, thus allowing <script> and we want to make it so that it isn't allowed in the markup declarations the template is using:

<!-- doc.dtd -->
<!element doc - - (sub|p|usercontent)+>
<!element sub - - (p+) +(script)>
<!element p O O (b|i|#pcdata)+>
<!element b - - (#pcdata)>
<!element i - - (#pcdata)>
<!element script - - cdata>
<!attlist sub ref entity #conref>
<!element usercontent - - (sub+) -(script)>

<!-- master.sgm -->
<!doctype test system "doc.dtd" [
  <!entity template "doesn't matter">
]>
<!linktype lnk [
  <!entity template system "template.sgm" ndata sgml>
]>
<doc><sub>blabla</sub><usercontent><sub ref=template></usercontent></doc>

<!-- (lax) template.sgm -->
<!doctype test system "doc.dtd">
<sub>formatted user contributed content</sub>

To implement enforcement of the contextual constraints on sub, as used in child content of usercontent elements, we change the DTD to use the script_or_noscript parameter entity for holding the exception string used in the DTD, ie. +(script) in the master's view of the DTD, and -(script) in the templates view, supplying the exception string-(script)` as template parameter in the latter case:

<!-- doc.dtd -->
<!element doc - - (sub|p|usercontent)+>
<!entity % script_or_noscript "+(script)">
<!element sub - - (p+) %script_or_noscript>
<!element p O O (b|i|#pcdata)+>
<!element b - - (#pcdata)>
<!element i - - (#pcdata)>
<!element script - - cdata>
<!attlist sub ref entity #conref>
<!element usercontent - - (sub+) -(script)>

<!-- master.sgm -->
<!doctype test system "doc.dtd" [
  <!entity template "doesn't matter">
]>
<!linktype lnk [
  <!notation template_notation public "... SGML pubid ...">
  <!attlist #notation template_notation script_or_noscript cdata #required>
  <!entity template system "template.sgm" ndata template_notation [script_or_noscript="-(script)">
]>
<doc><sub>blabla</sub><usercontent><sub ref=template></doc>

<!-- (lax) template.sgm -->
<!doctype test system "doc.dtd" [
  <!entity % script_or_noscript system>
]>
<sub>formatted user contributed content</sub>

Note that if we had placed +(script) on doc, and don't the template wouldn't be allowed to use <script> either because it's only introduced on doc and the template doesn't start on <doc> hence can't use <script>

Similarly, other limitations of strict templates can be solved using parameter entity techniques such as changing REFID attributes (in the master's DTD view) into enumerated value attributes (in the template's view), or changing ID attributes into #FIXED attributes.

Inline templates

Strict templates using an empty document prolog (which is interpreted as <!doctype #implied system> when the IMPLYDEF DOCTYPE YES feature is active) can be specified inline, rather than in an external file, like this (using a literal storage manager FSI):

<!doctype doc [
  <!element doc - - (sub+)>
  <!element sub - - (#pcdata)>
  <!attlist sub ref entity #conref>
  <!entity e system "doesn't matter">
]>
<!linktype lnk #simple #implied [
  <!notation sgml public "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
  <!entity e system "<literal><sub>text from referenced entity</sub>" ndata sgml>
]>
<doc><sub ref=e></doc>

Inline templates can reference template parameters as general entity references: when IMPLYDEF ENTITY YES is effective, any undeclared entity is implicitly declared system-specific, ie. treated as if it were declared <!ENTITY ent SYSTEM>. So if a template doesn't make use of parameter entities or other markup declarations, it can omit the document prolog and still reference template parameters. Note that parameter entities are not subject to IMPLYDEF ENTITY and must always be explicitly declared.

Use of templates in multi-stage processing pipelines

A template is processed in an isolated SGML processing context: the result of a template application can always be produced by processing the applied template SGML document in isolation, with supply of the same system-specific entities to the processing context as in a template application from an invocation context.

As a consequence, since the result markup of a template application is not fed-back into the invocation context. unlike result markup generated directly by link rules without templating, the result of a template application is not visible to the invocation processing context where the template is applied.

As a natural extension to the basic model for executing templates in processing sub-contexts by propagating DTD declarations into the sub-context, pipelining template result markup into downstream link processes is realized as propagating and activating link processing rules captured from a template invocation context into the processing subcontext executed on templates for link processing subcontexts.

An (explicit) link process, when part of a pipeline of multiple link processes, considers the activated link process following after it in the pipeline, if any, and derives a new link process from subsequent link process declarations and state at the context position as follows:

  • the current link state (the link rules declared for the current link set name at the context position where the template is applied) is reproduced as #INITIAL link set in the subcontext for the respective stage; if the current link set is a named link set (eg. not the #INITIAL link set), the declaration is replicated in addition

  • effective notation and link attribute declarations of the link process in the context of the invocation are copied over to the target link set declaration

For example, in the following document, the lnk2 (implicit) link process follows the lnk1 (explicit) process:

<!DOCTYPE a [
	<!ELEMENT (a|b) - - ANY>
]>
<!DOCTYPE x [
	<!ELEMENT (x|y) - - ANY>
]>
<!LINKTYPE lnk1 a x [
	<!NOTATION t SYSTEM "t.sgm"
		PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
	<!ATTLIST b template NOTATION (t) #IMPLIED>
	<!LINK #INITIAL
		a x                 -- map a to x --
		b [ template=t ] y  -- apply t on b -->
]>
<!LINKTYPE lnk2 x #IMPLIED [
	<!NOTATION x SYSTEM "s.sgm"
		PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
	<!ATTLIST y template NOTATION (s) #IMPILIED>
	<!LINK #INITIAL x #USELINK in-x-content>
	<!LINK in-x-content y [ template=s ]>
]>
<a><b></b></a>

If both the lnk1 and lnk2 processes are activated, when lnk1 applies the t template on the b element from input markup, the current link set of the lnk2 link process at the context position is the in-x-content link set. lnk1 replaces the b element by the result of processing the following document:

<DOCTYPE y>
<!LINKTYPE lnk2 y #IMPLIED [
	<!NOTATION x SYSTEM "s.sgm"
		PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
	<!ATTLIST y template NOTATION (s) #IMPILIED>
	<!LINK #INITIAL in-x-content y [ template=s ]>
	<!LINK in-x-content y [ template=s ]>
<y></y>

with activated link process lnk2, honoring the link process automaton state at the context position.

Note propagation of explicit link processes to template subcontexts is only available in sgmljs.net Pro.

For explicit link processes as the second or subsequent link process following a link process applying a template, the following restrictions apply

  • the result document type name of any active explicit link process following a link process containing a template application must be the same as the source document type name, and

  • the link rule at the context position of any explicit link process following a template application must be an identiy mapping, eg. the target element must be the same as the source element

Link rules to inherit can branch on a filter attribute or IDLINK in such a way that the link state transitions to a new current link set via #POSTLINK. Therefore, link/template processing captures the link state of an inherited link process at the context position, honoring the current link state in the chained link process.

For example, consider a link set declaration for lpd2 using #POSTLINK to toggle between link states to apply (further) templating on content received from upstream processing such that different templates are applied on occurence of x elements with odd and even count, respectively:

<!LINKTYPE lnk2 out #IMPLIED [
	<!NOTATION odd
  P  PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN"
         "odd.sgm">
	<!NOTATION even
	  PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN"
         "even.sgm">
	<!ATTLIST x template NOTATION (odd|even) #IMPLIED>
	<!LINK #INITIAL out #USELINK odd>
	<!LINK odd  x #POSTLINK even [ template=odd ]>
	<!LINK even x #POSTLINK odd [ template=even ]>
]>

A template invocation in the lnk1 link process (coming before the shown lnk2 link process) considers the link state transitioned to on the templated element in the inherited implicit link process, and will prepare a link process declaration reflecting odd or even link rules in the propagated #INITIAL link set.

Anticipating #POSTLINK rules, however, is limited in that the link state in the invocation context's idea of the lpd2 link state is only driven by a bare element token eg. without attributes, which would make a difference if attributes are used as filter attributes, or matching IDLINK apply in the processing sub-context.

As a customization feature, a link process declared in an SGML document invoked as template with the same name as an inherited/activated LPD will result in the inherited markup declaration to be ignored, and the markup declarations present in the document prolog for the respective link declaration set to be used instead.

With regular propagation of link process declarations in sub-contexts (without overriding inherited markup in the template's document prolog), since only ever at most a single implicit link process is derived and propagated to sub-contexts, the result doctype of a link process declaration is always the same as its source doctype.

However, when using a custom LPD overriding the link process declarations inherited from a master context, no checking of the type of link process and its result markup document type is performed - an LPD overriding an inherited template can be an explicit link, hence can be declared to produce a document type different from the one expected at the context position in the invocation context, and thus produce invalid markup with respect to the master context document type.

CONREF preemption and templating in pipelined templates

Note it's not necessary to handle #CONREF templates in chained subcontexts (and hence not necessary to propagate entity declarations to subcontexts). This is because #CONREF element markup events are forwarded to subsequent pipeline stages/link processes only with implicit LPDs. But SGML only allows a single implicit LPD in a chain, and only as the last stage.

If a preempted #CONREF entity is expanded in an explicit LPD, on the other hand, then new result markup is created, and #CONREF is not handled on result markup of explicit links, being required to come from actual content markup.

Query result set formatting pro

Templates can also be used for formatting query results from SQL or SPARQL databases.

SQL and SPARQL endpoints deliver query results in a tabular fashion, ie. as ordered result set of tuples (or rows), where a tuple is a set of item-value pairs mapping query column names to result value strings.

In query result formatting, the SGML processor invokes template processing on every row of a result set, and concatenates the produced markup of the (potentially more than one) template invocations into result markup.

Formatting query results involves

  • a query as a CDATA data entity in a query notation (ie. either in the SQL or he SPARQL notation as declared using either the +//IDN sgml-cms.net//NOTATION sql-query or the +//IDN sgml-cms.net//NOTATION sparql-query public identifier, respectively), and

  • a formatting template which receives and accesses bound column values as (system-specific) entities, and which is specified on the query template as value of a NOTATION attribute.

For example, the following file, biblio.sparql, contains a SPARQL query for fetching bibliography data from an external data source (in the vocabulary used by the Zotero blbliography management application):

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX res: <http://purl.org/vocab/resourcelist/schema#>
PREFIX z:   <http://www.zotero.org/namespaces/export#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT $item $resource $resourcetype $title $givenname $surname $name
FROM <zotero-bilbliography.rdf>
WHERE {
  $item rdf:type z:UserItem.
      $item res:resource $resource.
      $resource rdf:type $resourcetype.
      OPTIONAL {$resource dcterms:title $title}
      OPTIONAL {$resource dcterms:creator $creator}
      OPTIONAL {$creator rdf:type foaf:Person}
      OPTIONAL {$creator foaf:givenname $givenname}
      OPTIONAL {$creator foaf:surname $surname}
      OPTIONAL {$creator foaf:name $name}
}

The following SGML document executes the query against the zotero-bibliography.rdf RDF file containing bibliography data exported from Zotero, and formats the results via an inline template:

<!DOCTYPE HTML [
  <!ELEMENT HTML O O (DIV|P)+>
  <!ELEMENT DIV - O (#PCDATA|P|SPAN)+>
  <!ELEMENT P O O (#PCDATA|A)+>
  <!ELEMENT SPAN - - (#PCDATA)>
  <!ATTLIST SPAN PROPERTY CDATA #IMPLIED>
  <!ELEMENT A - - (#PCDATA)>
  <!ATTLIST A HREF CDATA #IMPLIED TITLE CDATA #IMPLIED>
  <!ENTITY bibliography_rdf_graph_ns "http://zotero.org/users/local/Rk1rxAG1/items/">
  <!ENTITY bibliography_rdf_graph_location "zotero-bibliography.rdf">
  <!ATTLIST DIV REF ENTITY #CONREF PROPERTY CDATA #IMPLIED>
  <!ENTITY bibliography "placeholder">
]>
<!LINKTYPE BIBLIOGRAPHY #SIMPLE #IMPLIED [
  <!NOTATION SGML PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
  <!NOTATION BIBLIO PUBLIC "+//IDN sgml-cms.net//NOTATION sparql-query">
  <!ATTLIST #NOTATION BIBLIO
      SUPERDCN NAME #FIXED SGML
      TEMPLATE NAME #REQUIRED
      ENDPOINT CDATA #FIXED "roqet --quiet --results tsv --exec">
  <!NOTATION BIBLIOENTRY
      SYSTEM '<literal>
            <div property="dcterms:creator">
              <span property="foaf:givenname">&givenname</span>
              <span property="foaf:surname">&surname</span>
              <span property="foaf:name">&name</span></div>'>
  <!ATTLIST #NOTATION BIBLIOENTRY
      SUPERDCN NAME #FIXED SGML
      GIVENNAME CDATA #IMPLIED
          SURNAME CDATA #IMPLIED
          NAME CDATA #IMPLIED>
  <!ENTITY BIBLIOGRAPHY SYSTEM "biblio.sparql" NDATA BIBLIO [ TEMPLATE=BIBLIOENTRY ]>
]>
<html>
...
<h2>Bibliography</h2>
<div ref=bibliography>
</html>

As shown in the following sections, SPARQL and SQL queries can also be supplied inline as notational content (rather than via an external file).

Query parameters

Data attributes of a query notation (other than the template data attribute which is treated special as described) are supplied as substitution variables to the SPARQL or SQL query processor and can be referenced in the query notation code text in a similar way as entity references in SQL code text.

For example, the following declaration of a SPARQL query notation takes the color query parameter and substitutes the supplied value in place of the &color parameter reference:

<!notation sgml ...>
<!notation query public "+//IDN sgml-cms.net//NOTATION sparql-query">
<!attlist #notation query
	superdcn name #fixed sgml
	template name #required
	color cdata #required>

<!entity flower-by-color-query system "<literal>
	PREFIX plants: <http://plants.org/plants-vocabulary-1.0/>
	SELECT ?flower
	WHERE { ?flower :color &color }"
	ndata query [ template=... color="yellow" ]>
]>

Note that even though the & (ampersand) character is used in SGML, SPARQL, and SQL in a similar way, recognition and interpretation of "entity references" in query notation content is still handled in a query-notation specific way.

Note query parameters are supplied to the query processor and are not automatically supplied to the query result formatting template.

The SPARQL processor used by sgmljs.net will evaluate SPARQL queries against a local default tuple store (ie. database); see SPARQL examples on how to supply a specific SPARQL endpoint (IP address or DNS name or a particular RDF file) to query.

SQL queries

The same technique used for SPARQL can also be used with SQL. For example, the following document formats the results of an inline SQL query to query all stored names when using GENDER_CD 0 as query parameter (it also demonstrates use of connection parameters):

<!DOCTYPE HTML [
	<!ELEMENT HTML O O (DIV|P)+>
	<!ELEMENT DIV - O (#PCDATA|P|SPAN)+>
	<!ELEMENT P O O (#PCDATA|A)+>
	<!ELEMENT SPAN - - (#PCDATA)>
	<!ELEMENT A - - (#PCDATA)>
	<!ATTLIST DIV REF ENTITY #CONREF PROPERTY CDATA #IMPLIED>
	<!ENTITY femalenames "placeholder">
]>
<!LINKTYPE LISTBOOKS #SIMPLE #IMPLIED [
	<!NOTATION SGML PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language (SGML)//EN">
	<!NOTATION SQLQUERY PUBLIC "+//IDN sgml-cms.net//NOTATION sql-query">
	<!ATTLIST #NOTATION SQLQUERY
		SUPERDCN NAME #FIXED SGML
		TEMPLATE NAME #REQUIRED
		GENDER_CD CDATA #REQUIRED
		SQLITE_DB_FILE CDATA #REQUIRED>
	<!NOTATION NAMEENTRY SYSTEM '<literal><div><span>&name</span></div>'>
	<!ATTLIST #NOTATION NAMEENTRY
		SUPERDCN NAME #FIXED SGML
		NAME CDATA #IMPLIED>
	<!ENTITY femalenames SYSTEM "<literal>
set colsep '	'
set underline off
connect 'Driver=SQLite;Database=&sqlite_db_file'
select name from names_tbl where gender_cd = cast('&gender_cd' as decimal);"
		NDATA SQLQUERY [ TEMPLATE=NAMEENTRY GENDER_CD="0" SQLITE_DB_FILE="/Users/guesswho/Repositories/markdown-awk/test/test.db" ]>
]>
<html>
<div ref=femalenames>
</html>

When supplying values to SQL, the SGML processor will allways escape single quotes occuring in supplied values into double quotes.

SQL queries should always use received values as string literals, ie. in single quotes.