Topic Constraint Module: XSD-Syntax Version
XSD constraint modules consist of one or two XSD documents that redefine the content
model or
attribute list to be constrained. Whether the constraint requires one document or
two
depends on the details of the constraint being applied and the group being constrained.
This particular constraint requires an intermediate XSD file to work around limitations
in the way the redefine feature works. Essentially, we have to clear the content of
<p>
and then extend it, which requires two levels of redefinition.
- Create a new directory to hold the constraint module and an XSD document type shell that uses it. This directory will eventually be the directory for the constraint module, so name it in a way that reflects the name of the constraint module, for example, "highlightOnlyPConstraints."
- Copy topic.xsd from the technicalContent
directory of the OASIS-provided DITA XSD distribution to this new directory.
Name it something like topic-with-highlight-constraint.xsd
to make it clear what this shell is for.
Eventually you will move this shell schema to a different directory, but for now putting all the pieces in one directory makes setup and testing easier. Once everything is working in this location you can reorganize the files and know when you've got everything hooked up right again.
- In the same directory, create a new XML document that uses the shell XSD. This document
is
used to test as you go. Name it something like
constraint-test.xsd. Verify that the document is valid.
As you haven't yet modified the shell schema document, it should be valid. The
document should look something like
this:
<?xml version="1.0" encoding="UTF-8"?> <topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="topic-with-highlight-constraint.xsd" id="topicid"> <title>Test of Simple Paragraph Restriction</title> <body> <p><b>b</b>, <i>i</i>, <u>u</u>. Not allowed <keyword>keyword</keyword>.</p> <p></p> </body> </topic>
- In the same directory, create a new empty XSD document named highlightOnlyPConstraints.xsd. This is the constraint module file.
- For this domain you are constraining the content model of the
<p>
element, so the first task is to find where<p>
's content model is defined in the XSD files that make up the base<topic>
vocabulary module. One way to do this is to search for name="p.content" across all the standard XSD modules (for example, using OxygenXML's "Find in files" feature or using Search in Windows Explorer). You should find the group definition for "p.content" in commonElementMod.xsd. It looks like this:<xs:group name="p.content"> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="para.cnt" minOccurs="0"/> </xs:choice> </xs:sequence> </xs:group>
- Create the intermediate redefinition file highlightOnlyPConstraintsInt.xsd and give it this content:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:annotation> <xs:documentation>Intermediate level of redefine to work around XSD redefine limitations </xs:documentation> </xs:annotation> <xs:redefine schemaLocation="urn:oasis:names:tc:dita:xsd:commonElementMod.xsd:1.2"> <!-- constrain content of <p> element --> <xs:group name="p.content"> <xs:choice> <!-- "clear" p.content so we can then override it again in the next level of redefine. --> </xs:choice> </xs:group> </xs:redefine> <xs:group name="p-highlight-only.content"> <xs:choice> <xs:sequence maxOccurs="unbounded"> <xs:group ref="b" minOccurs="0"/> <xs:group ref="i" minOccurs="0"/> <xs:group ref="u" minOccurs="0"/> </xs:sequence> </xs:choice> </xs:group> </xs:schema>
This schema document redefines
<p>
as declared in commonElementMod.xsd to be an empty group. This document also defines a new group containing the new content model we want for<p>
. - In the new constraint module XSD file, create an
<xs:redefine>
element that points highlightOnlyPConstraintsInt.xsd and defines "p.content" to use the "p-highlight-only.content" content group also defined in highlightOnlyPConstraintsInt.xsd:<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:redefine schemaLocation="highlightOnlyPConstraintsInt.xsd"> <!-- constrain content of <p> element --> <xs:group name="p.content"> <xs:choice> <xs:group ref="p-highlight-only.content"/> </xs:choice> </xs:group> </xs:redefine> </xs:schema>
- To the topic document type shell XSD add the statement in bold between the two statements
shown:
... <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:topicMod.xsd:1.2"/> <xs:include schemaLocation="highlightOnlyTopicConstraints.xsd" /> <xs:group name="info-types"> <xs:sequence/> </xs:group> ...
This includes the constraint module in the XSD document type shell.
- In the topic document type shell, remove or comment out the include of
commonElementMod.xsd, since it is now included by the
redefine statement in the intermediate XSD
document:
<!-- ================= MODULE INLCUDE DEFINITION ================== --> <!-- <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:commonElementMod.xsd:1.2"/> -->
- Test your work by validating your test document. It should validate (meaning all the
schema components are hooked up). Make sure your test document has a paragraph
with something other than
<b>
,<i>
, or<u>
in it (e.g.,<keyword>
). - Update the domains attribute declaration in the document type shell to reflect the
use of the constraint module:
... <xs:attributeGroup name="domains-att"> <xs:attribute name="domains" type="xs:string" default="(topic highlightOnlyP-c) (topic ui-d) (topic hi-d) (topic sw-d) (topic pr-d) (topic ut-d) (topic indexing-d) (topic hazard-d) (topic abbrev-d)"/> </xs:attributeGroup> ...
- Test the constraint by validating your test document. It should be valid and should
only allow
<b>
,<i>
, and<u>
within<p>
.
At this point you could package the constraint module and the shell document type into Toolkit plugins.