Your project is coming along nicely. You have your workflow ready, your style guides are composed, and things are looking up. However, you have complex metadata needs that are starting to cause problems. You need a way to ensure that authors are only using valid attribute values, and that your publication pipeline isn’t going to suffer. This is a situation that calls for a subjectScheme.
Normally, most DITA attributes can have any text value. If you have very specific needs for your attribute metadata, it can be helpful to make sure that you only allow certain values. A subjectScheme allows you to define a list of values that are then associated with a specific attribute. When you include a subjectScheme in your map, it acts like an editor, going through your document and ensuring that your attribute values are valid.
Anatomy of a subjectScheme
A subjectScheme map consists of a root <subjectScheme> element that contains the following:
- a <subjectdef> element, which defines your allowed values
- an <enumerationdef> element, which binds your allowed values to a specific attribute
Take a look at this sample subjectScheme:
We need to assign values to an attribute named app. The <attributedef> element identifies that attribute, and the <subjectdef> element after it assigns the allowed values. The nested <subjectdef> elements above the <enumerationdef> list five values (internal, external, allowedex, disallowedex, and all) that we consider valid. If we take this and reference it in a map, any app attribute containing anything other than those five values will cause the document to fail validation.
Also, notice that the <subjectdef> elements that define allowedex and disallowedex are nested in the <subjectdef> element that defines external. This indicates that allowedex and disallowedex are types of external apps, creating a semantic link between these types.
To use a subjectScheme in a map, you need to use the following format when referencing it:
<topicref href="filename" format="ditamap" type="subjectScheme"/>
Effects on conditional filtering
We’ve already discussed conditional filtering in a previous blog post. If you’re using a ditaval filter file to conditionally process content, the relationship between values defined in your subjectScheme map comes into play.
Let’s say that you have a ditaval file which includes the following:
<prop action=”include” att=”app” val=”internal”/>
<prop action=”exclude” att=”app” val=”external”/>
<prop action=”include” att=”app” val=”all”/>
If you run your content with this filter, elements that have an app value of internal or all will be included, and elements with an app value of external will be excluded. However, values of allowedex and disallowedex will still be included in your output, and you would need to include specific handling for those values.
If your map included a subjectScheme, though, the only elements that would come through would be those with an app value of internal or all. This is because of the semantic relationship that is defined within the subjectScheme. Because external apps are excluded and because the subjectScheme defines allowedex and disallowedex as a type of external app, allowedex and disallowedex are also excluded.
By using a subjectScheme map to enrich your attribute metadata, you not only gain a way to define valid values, but also a way to create relationships between them.