Skip to content

Built-in DITA schema

oasis:dita-metadata:1.3 describes the typed metadata elements OASIS defines for a DITA topic or map. Those are the <prolog> and <topicmeta> contents that docmeta reads through the element metadata rule.

It is named dita-metadata rather than dita-prolog because it constrains topicmeta.* too, and a name saying prolog would be wrong for every map.

Cardinality comes from the content model, not from a guess: author* is a list, source? is a scalar.

Key Source in a topic Type
prolog.author <prolog><author> list
prolog.source <prolog><source> string
prolog.publisher <prolog><publisher> string
prolog.permissions <permissions @entitlement> string
prolog.resourceid <resourceid @id> list
critdates.created <critdates><created @date> date string
critdates.revised <critdates><revised @modified> list of date strings
metadata.audience <metadata><audience @type> list
metadata.category <metadata><category> list
copyright.copyryear <copyright><copyryear @year> list
copyright.copyrholder <copyright><copyrholder> string
keywords.keyword <keywords><keyword> list
keywords.indexterm <keywords><indexterm> list
prodinfo.prodname <prodinfo><prodname> string
prodinfo.brand.series <prodinfo>’s six-element choice group list
vrm.version / .release / .modification <vrmlist><vrm @…> list

In a map the five prolog.* keys are topicmeta.*, and audience and category are topicmeta.audience and topicmeta.category. critdates.* and prodinfo.prodname are identical in both.

DITA marks no metadata element mandatory, so neither does this. Turning it on cannot fail a topic that was building. It checks the shape of what a topic already carries.

The one format rule it does impose is on dates. @date and @modified are CDATA in the DTD, so DITA itself accepts anything; the schema requires YYYY-MM-DD, which is what DITA-OT and the toolchains around it assume. A date nothing validates is a date that drifts.

A topic may carry the same fact twice:

<prolog>
<metadata>
<audience type="programmer"/>
<othermeta name="audience" content="42"/>
</metadata>
</prolog>

That is two keys, metadata.audience and the flat audience, and both are checked. Neither wins. A precedence rule would discard one, and the discarded one is exactly the one nobody is looking at.

<othermeta> keys are not described by this schema, because their names are yours. Pair it with a schema of your own if you want them constrained.

Terminal window
docmeta fill docs/**/*.dita -s oasis:dita-metadata:1.3
  • An element that exists has its text or attribute value replaced. That cannot change whether the topic is valid, because it changes content and not shape.
  • An element that is missing is created, along with any containers it needs, at the position the content model requires. So <critdates> goes after <author> and before </prolog>, rather than merely appended.
  • A key with no place in the content model still goes to an <othermeta>, which is where a key the DTD has no home for belongs.
  • Adding or removing a repeated element is refused. Writing three authors over two <author> elements changes the topic’s shape, which docmeta will not do on your behalf.

Every DITA document docmeta writes is checked against the OASIS content models, which children a container may hold, in what order, and how many times. Those are the only constraints a splice-only writer can break: it never invents attributes and never reorders existing children.

The models are transcribed by hand from the specification in the test suite. They are deliberately not imported from the table the writer writes from. Checking one against the other would prove only that it is self-consistent.

It does not cover attribute value types, required attributes, entity resolution, or specialization @class ancestry. No DITA DTD validator exists in this toolchain. Vendoring the OASIS grammar is about a megabyte of DTD modules, to check element order in a handful of files.