Structure Schematron Rules
You can use the following rules to enforce extra validation of your information architecture.
Do not insert elements into title elements
A title element cannot contain any children elements except for conkeyrefs.
Flag
Code
<!-- A Title element cannot contain any children elements except for conkeyrefs. -->
<pattern id="STRUCTURE_01">
<rule context="title">
<report test="*[not(@conkeyref)]">A title element cannot contain any children elements except for conkeyrefs.</report>
</rule>
</pattern>
Assign @xml:lang attributes to root topic elements
Each root topic element should have an @xml:lang attribute assigned.
Flag
Code
<!-- Each topic root element should have an @xml:lang attribute assigned -->
<pattern id="STRUCTURE_02">
<rule context="concept|task|reference|topic|troubleshooting">
<assert test="@xml:lang">Each root topic element should have an @xml:lang attribute
assigned.</assert>
</rule>
</pattern>
Add Short Description elements
Each topic should contain a Short Description element.
Flag
Code
<!-- Each topic should contain a Short Description element -->
<pattern id="STRUCTURE_03">
<rule context="concept|task|reference|topic|troubleshooting">
<assert test="shortdesc|abstract/shortdesc">Topics should contain a Short
Description element.</assert>
</rule>
</pattern>
Do not create one-step procedures
Each task should contain at least two Step elements.
Flag
Code
<!-- Each task should contain at least two Step elements -->
<pattern id="STRUCTURE_04">
<rule context="steps">
<assert test="count(step) > 1">Tasks should contain at least two Step elements.
If you need to create a one-step task, replace the Steps element with a
Steps-Unordered element.</assert>
</rule>
</pattern>
Do not duplicate children elements in step elements
A Step or Substep element should not contain more than one Choices, Substeps, Step Example, or Info element.
Flag
Code
<!-- A Step or Substep element should not contain more than one Choices, Substeps, Step Example, or Info element -->
<pattern id="STRUCTURE_05">
<rule context="step|substep">
<assert test="count(info) < 2">A Step or Substep element should not contain more than one Info
element.</assert>
<assert test="count(stepxmp) < 2">A Step or Substep should not contain more than one Step
Example element.</assert>
<assert test="count(choices) < 2">A Step or Substep should not contain more than one Choices
element.</assert>
<assert test="count(substeps) < 2">A Step should not contain more than one Substeps
element.</assert>
</rule>
</pattern>
Do not create one-substep substeps
A Substeps element should contain at least two Substep elements.
Flag
Code
<!-- A Substeps element should contain at least two Substep elements -->
<pattern id="STRUCTURE_06">
<rule context="substeps">
<assert test="count(substep) > 1">A Substeps element should contain at least two
Substep elements.</assert>
</rule>
</pattern>
Do not create one-choice choices
A Choices element should contain at least two Choice elements.
Flag
Code
<!-- A Choices should contain at least two Choice elements -->
<pattern id="STRUCTURE_07">
<rule context="choices">
<assert test="count(choice) > 1">A Choices element should contain at least two Choice
elements.</assert>
</rule>
</pattern>
Remove or fill in empty elements
Empty task elements should be removed or filled in. Do not flag reused step elements in the target file.
Flag
Code
<!-- Empty task elements should be removed or filled in but not flag conrefs -->
<pattern id="STRUCTURE_08">
<rule context="//step[not(@conref)]/cmd|//substep[not(@conref)]/cmd|prereq[not(@conref)]|postreq[not(@conref)]|stepresult[not(@conref)]|steps-unordered[not(@conref)]|stepsection[not(@conref)]|cause[not(@conref)]|condition[not(@conref)]|result[not(@conref)]|stepxmp[not(@conref)]|context[not(@conref)]|info[not(@conref)]">
<assert test="string-length(.) != 0">Empty task elements should be removed or filled in.</assert>
</rule>
</pattern>
Add titles for sections
A Section element should contain a Title element.
Flag
Code
<!-- A Section element should contain a Title element -->
<pattern id="STRUCTURE_09">
<rule context="section">
<assert test="title">A Section element should contain a Title element.</assert>
</rule>
</pattern>
Do not add introductory text
Prerequisites, Postrequisites, Step Example, Step Result, Example, Result, and Context elements should not contain introductory text. The text is generated automatically (specific to: heretto_pdf, color_pdf, and gray_pdf publishing scenarios).
Flag
Code
<!-- Prerequisites, Postrequisites, Step Example, Step Result, Example, Result, and Context elements should not contain introductory text. The text is generated automatically (Specific to: heretto_pdf, color_pdf, gray_pdf publishing scenarios) -->
<pattern id="STRUCTURE_10">
<rule context="prereq/p[1]">
<report test="matches(., '^[Bb]efore\s*you\s*[Bb]egin')">Remove the introductory text. The
text is generated automatically.</report>
<report test="matches(., '^[Bb]efore\s*you\s*[Ss]tart')">Remove the introductory text. The
text is generated automatically.</report>
<report test="matches(., '^[Pp]rerequisites')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
<rule context="postreq/p[1]">
<report test="matches(., '^[Nn]ext\s*[Ss]teps')">Remove the introductory text. The text is
generated automatically.</report>
<report test="matches(., '^[Pp]ostequisites')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
<rule context="stepxmp/p[1]|example/p[1]">
<report test="matches(., '^[Ee]xample')">Remove the introductory text. The text is
generated automatically.</report>
<report test="matches(., '^[Ff]or\s*[Ee]xample')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
<rule context="stepresult/p[1]|stepresult/p[1]">
<report test="matches(., '^[Rr]esult')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
<rule context="result/p[1]|result/p[1]">
<report test="matches(., '^[Rr]esult')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
<rule context="context/p[1]">
<report test="matches(., '^[Cc]ontext')">Remove the introductory text. The text is
generated automatically.</report>
</rule>
</pattern>
Do not create one-item unordered or ordered lists
Unordered List and Ordered List elements should contain at least two List Item elements.
Flag
Code
<!-- Unordered List and Ordered List elements should contain at least two List Item elements -->
<pattern id="STRUCTURE_11">
<rule context="ul|ol">
<assert test="count(li) > 1" sqf:fix="addListItem">Unordered List and Ordered List
elements should contain at least two List Item elements.</assert>
<sqf:fix id="addListItem">
<sqf:description>
<sqf:title>Add a List Item element</sqf:title>
<sqf:p>To fix this issue, you can add another List Item element. If you cannot
come up with another List Item element, convert the list element to a Paragraph
element.</sqf:p>
</sqf:description>
<sqf:add node-type="element" target="li" position="last-child"/>
</sqf:fix>
</rule>
</pattern>
Do not create one-item definition lists
A Definition List element should contain at least two Definition Entry elements.
Flag
Code
<!-- A Definition List element should contain at least two Definition Entry elements -->
<pattern id="STRUCTURE_12">
<rule context="dl">
<assert test="count(dlentry) > 1">A Definition List element should contain at least
two Definition Entry elements.</assert>
</rule>
</pattern>
Do not wrap images in paragraphs
A non-inline Image element should be wrapped in a Figure element instead of a Paragraph element.
Flag
Code
<!-- An Image element should be wrapped in a Figure element instead of a Paragraph element -->
<pattern id="STRUCTURE_15">
<rule context="p">
<report test="image">An image element should be wrapped in a Figure element instead of a
Paragraph element.</report>
</rule>
</pattern>
Add an alt element for each image
To ensure that your content is accessible, all Image elements should contain an Alt element.
Flag
Code
<!-- An Image element should contain an Alt element -->
<pattern id="STRUCTURE_16">
<rule context="image">
<assert test="alt">An Image element should contain an Alt element.</assert>
</rule>
</pattern>
Specify the images width
An image element should have the @width attribute assigned.
Flag
Code
<!-- An image element should have the @width attribute assigned (Specific to: DITA Open Toolkit-Specific publishing scenarios) -->
<pattern id="STRUCTURE_18">
<rule context="image">
<assert test="@width">An image element should have the @width attribute
assigned.</assert>
</rule>
</pattern>
Specify the type attribute for each note
Each Note element should have the @type attribute assigned.
Flag
Code
<!-- Each Note element should have the @type attribute assigned -->
<pattern id="STRUCTURE_19">
<rule context="note[not(@conref)]">
<assert test="@type">Each Note element should have the @type attribute
assigned.</assert>
</rule>
</pattern>
Do not add tables without headers
A Table element should contain a Table Header (thead) element.
Flag
Code
<!-- A Table element should contain a Table Header (thead) element -->
<pattern id="STRUCTURE_20">
<rule context="table">
<assert test="//thead">A Table element should contain a Table Header (thead)
element.</assert>
</rule>
</pattern>
Do not create single-item menu cascades
A Menu Cascade element should contain at least two UI Control elements.
Flag
Code
<!-- A Menu Cascade element should contain at least two UI Control elements -->
<pattern id="STRUCTURE_21">
<rule context="menucascade">
<assert test="count(uicontrol) > 1">A Menu Cascade element should contain at least two
UI control elements.</assert>
</rule>
</pattern>
Add an attribute to fit wide tables
A topic that contains a Table element with five or more columns should have the @outputclass="landscape" attribute assigned to the root topic element.
Flag
Code
<!--A topic that contains a Table element with five or more columns should have the @outputclass="landscape" attribute assigned to the root topic element -->
<pattern id="STRUCTURE_22">
<rule
context="concept[not(@outputclass='landscape')]//table/tgroup|task[not(@outputclass='landscape')]//table/tgroup|reference[not(@outputclass='landscape')]//table/tgroup|topic//table/tgroup|troubleshooting//table/tgroup">
<report test="count(colspec) > 4">A topic that contains a Table element with five or
more columns should have the @outputclass="landscape" attribute assigned to the root
topic element.</report>
</rule>
</pattern>
Do not use non-semantic elements
Do not use non-semantic elements (bold, underline, italics) to format content.
Flag
Code
<!-- Do not use non-semantic elements (bold, underline, italics) to format content -->
<pattern id="STRUCTURE_23">
<rule context=".">
<report test="b|u|i">Do not use non-semantic elements (bold, underline, italics) to format content. Consider using a Window Title or a UI Control element.</report>
</rule>
</pattern>