Structured content can have various levels of complexity, from simple sequences of form fields — titles and descriptions, metadata values from lists, and body fields — to more elaborate sequences and nested structures. The latter can be particularly useful in regulated contexts such as legal or medical documentation, but aren’t by any means limited to those. Generally speaking, the better defined a content model can be, the more consistent and informational the content is, and the greater the potential benefits.
One way of ensuring control of content structures is to use XML-aware authoring tools such as Oxygen or FontoXML. These editors validate content against XML schemas — documents that define the permitted structures using syntaxes such as DTD, XML Schema (with a capital S), and RELAX NG. The authoring tools themselves can be configured to make authoring in XML visually appealing and accessible to non-specialists. However, setting up schemas in the first place or improving existing ones isn’t so easy.
Authors and managers must be consulted to make sure the formal structures work both in terms of intended outputs and in terms of the authoring experience. The structures should support authors’ mental models of the content they write. To aid this process, a clear visualization of the whole content model would be very helpful. Sometimes, information architects represent aspects of content models with Visio-style boxes and connectors. This works well when examining the detail of a model, but the full context of that detail — the whole topic or document model — rapidly gets too much to view on one screen or page. In addition, updating a diagram such as this takes time and isn’t well suited to collaborative development on the fly during a meeting.
Most commonly, schema developers are stuck with the raw schema syntax. Here, for example, is part of the task DTD based on the DITA XML 1.2 standard.
<!— LONG NAME: Step —>
<!ENTITY % step.content
“((%note;)*,
%cmd;,
(%choices; |
%choicetable; |
%info; |
%itemgroup; |
%stepxmp; |
%substeps; |
%tutorialinfo;)*,
(%stepresult;)? )”
>
This extract controls the elements that can go directly within a procedural step
element. It allows for any number of note
elements, followed by an obligatory cmd
(a command; the core of the procedural step), followed by any number of choices
/ choicetable
/ info
/ itemgroup
/ stepxmp
/ substeps
/ tutorialinfo
elements in any order, followed by an optional stepresult
. (While this might seem fussy and unnecessarily limiting if you are not used to working with such detailed content models, the thinking behind it is clear: any step should have an action-oriented sentence but notes should be read before that sentence; and other information might be helpful but there can only be one result of a well-specified step.)
The step element is one of quite a few allowed elements in a DITA task, and each has its own defined content model in the DTD. It is obvious that seeing a big list of these content models isn’t necessarily the most accessible way to get an idea of DITA task structure, or to work with modifications of that structure (DITA is designed to enable more constrained or specialized content models based on the “out of box” types.)
Over the last couple of weekends, I’ve been refining a framework for visualizing schemas that:
- Provides an accessible way for authors, managers, and schema developers alike to understand or refine a content model.
- Is easy to update and maintain without specialist tools or knowledge1.
- Offers a single-page view of the whole content model at a glance, rather than the common approach of revealing only certain aspects of the model in each view. While it can sometimes be helpful to focus on details of the model, the full picture is very helpful for putting the detail in context and working with the model in a way that’s easily grasped. (As is often the case with conceptual architectures, printing the visualization out and doodling/handwriting notes on it could be particularly useful for collaborative schema development)[^1].
- Is structured enough that it could be parsed to generate at least a skeleton formal schema such as a DTD.
- Is general enough that it can be used for any content model, whether that model will be implemented in DITA XML, other XML languages, other markup standards such as SGML, or perhaps even a schema that isn’t based on markup, such as the model for a relational database.
I call it a spatial schema. It’s authored in a spreadsheet tool such as Google Sheets. Here’s an example of a somewhat constrained DITA task topic model using this framework:

The rules for reading this are:
- The nested boxes represent the hierarchy of elements: which elements are contained by which.
- The name at the top left of a box (or in the middle of a box) is the element name.
- The indent level represents the level in the hierarchy.
- Multiple separate boxes at the same level indicate that those elements are in sequence: the latter ones follow the former. For example, an optional
abstract
element follows an optionaltitlealts
, which follows a mandatorytitle
.abstract
cannot come beforetitle
. - Multiple items in a single box indicate multiple options at that point in the sequence. For example, after
cmd
, there can be any number ofchoices
/choicetable
/info
/itemgroup
/stepxmp
/substeps
elements in any order. - The number at the top right of a box signifies the number of the box’s elements that can appear within the box’s direct container. For example:
- 0+ means any number, e.g. the
note
orhazardstatement
elements at the beginning of astep
. - 1 in the same box would mean that there must be either a
note
or ahazardstatement
at the beginning of astep
, but not both.
- 0+ means any number, e.g. the
- Inline elements such as
ph
are not represented directly, to keep the visualization simple and specific to the topic type itself. - You should read the contents of the last descendants of any element as text data and inline elements. For example,
cmd
may only contain inline elements; no block elements.
To see the source document and copy it for your own use, view this Google Sheets document.
Benefits of this visualization framework
- The model for the whole document type (at least the elements) is represented in a reasonably compact and accessible manner.
- As it’s authored in a spreadsheet tool, it’s easy to use other columns to the left of the diagram for notes, descriptions of XML attributes that are part of the content model, or any other relevant info. For example, I used one column for the DITA inheritance path, and another to indicate where this model was different from the base, unspecialized one.
- As it follows a consistent structure, it would be possible to generate a skeleton schema document from it. From a coding point of view, one way to start would be to export the sheet as a comma separated values file (
.csv
), and build an internal representation of the document model based on the first column in which an element name appeared (the indent level) and the number (if any) contained in that row.
Limitations
- In the main visualization itself, there’s currently no room to include XML attributes that are part of the content model, although they can be described in adjacent columns of the sheet.
- There is a practical limit to the degree of nesting that can be visualized in this way, and so generic block elements are indicated as [regular block element]. A similar approach should be taken with nested topics — the recursion can be indicated but left at that. This could, however, be seen as an advantage rather than a limitation — authors and users alike can get lost in deeply nested structures, and a rule of thumb might be that unless you can visualize a structure, you shouldn’t write content using it![^1]
- There is no provision for directly describing conditionally dependent relationships: “if this optional element is present then another one must be too”.
Here is one example of the latter from the experimental troubleshooting task specialization included with Oxygen XML, drawn from the DITA 1.3 spec in development:
<!— LONG NAME: Remedy —>
<!ENTITY % remedy.content
“((%title;)?, (%responsibleParty;)?,
(%steps; |
%steps-unordered; |
%steps-informal;)
)?”
>
This says that the remedy
element can be empty, i.e. with no content, but if it has any content, it must have one of steps
, steps-unordered
, or steps-informal
. A workaround to represent this using the spatial schema framework would be to use a dummy/virtual container for the child elements:

However, this type of structure does not seem to be needed very often in any case.
Here’s the link to the demo Google Sheet again. Let me know what you think in the comments. Could this be helpful to you? Is there anything that could be tweaked to improve it?
1
These items added to clarify the intent of the visualization framework, in response to Jang Graat’s helpful comment.
That’s a very nice visualization method. It’s very intuitive and easy to read. Further on, it’s great for rapid-prototyping (defining specialization requirements before implementing them).
LikeLiked by 1 person
Thanks, Stefan! I’m glad you found it useful.
LikeLike