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 two depends on the details of the constraint being applied and the group being constrained. This particular constraint requires an intermediate XSD file in order 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.

To create an XSD version of the highlight-only topic constraint module, follow these steps:
  1. 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, e.g. "highlightOnlyPConstraints".
  2. 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.

  3. 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>
  4. In the same directory, create a new empty XSD document named "highlightOnlyPConstraints.xsd. This is the constraint module file.
  5. 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>
  6. 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>.

  7. 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>
  8. 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.

  9. 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"/> -->
  10. Test your work so far 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>).
  11. 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>
    
      ...
  12. 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.