RELAX NG and DITA: An Almost Perfect Match

31
RELAX NG and DITA: An Almost Perfect Match How RELAX NG makes everything easier for DITA vocabulary 06/28/2022 Contrext, LLC 1 Eliot Kimber Contrext, LLC George Bina Synchro Soft Balisage 2014

Transcript of RELAX NG and DITA: An Almost Perfect Match

Page 1: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 1

RELAX NG and DITA: An Almost Perfect Match

How RELAX NG makes everything easier for DITA vocabulary

Eliot KimberContrext, LLCGeorge BinaSynchro SoftBalisage 2014

Page 2: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 2

About the Authors• Eliot Kimber

– Independent consultant focusing on DITA analysis, design, and implementation

– Doing SGML and XML for cough 30 years cough– Founding member of the DITA Technical Committee– Founding member of the XML Working Group– Co-editor of HyTime 2nd Edition standard (ISO/IEC 10744)– Primary developer and founder of the DITA for Publishers project– Author of DITA for Practitioners, Vol 1 (XML Press)

• George Bina– Founding partner of Syncro Soft SRL, makers of oXygen XML– Contributor to many open-source projects, including DITA-NG and oNVDL– More than 15 years experience working with XML and related technologies

Page 3: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 3

Agenda• Overview of DITA’s modular vocabulary

architecture• How DTDs don’t work too well for it• How XSDs work even less well• How RELAX NG does things almost perfectly

Page 4: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 4

Executive Summary• DITA depends on parameterized content models and

attributes to implement integration, extension, and constraint

• The available document grammar technologies support this to varying degrees– DTD: Works but tedious, verbose, and error prone– XSD: Almost works, tedious, verbose, not reliable or

interchangeable. Redefine feature is evil.– RELAX NG: Works with minimum verbosity and maximal ease

• Use of RELAX NG enables generation of conforming DTD and XSD versions of DITA grammars.

Page 5: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 5

DTD: Works but barely

Page 6: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 6

XSD: Works But Not For This Purpose

Page 7: RELAX NG and DITA: An Almost Perfect Match

Contrext, LLC 7

RELAX NG: Just Right

Balisage 2014

Page 8: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 8

OVERVIEW OF DITA VOCABULARY ARCHITECTURE

Page 9: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 9

Relevant DITA Facts• DITA 1.2 is current version. • DITA 1.3 in progress, target YE 2014/1Q2015• DITA standardizes the coding patterns for vocabulary

implementations in specific XML grammar languages– DITA 1.2: DTD and XSD. DTD and XSD maintained independently– DITA 1.3: RELAX NG, DTD, and XSD. DTD and XSD generated from

RELAX NG• Conforming vocabulary implementations must reflect these

coding standards• There is no single “DITA DTD”: All working grammars are

“local” to a given group of DITA users

Page 10: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 10

DITA Vocabulary Composition

Document Type Shell 1

Document Type Shell 2

Document Type Shells

Vocabulary Modules (Invariant)

Topic Type A

Topic Type B

Constraint K

Domain Y

Domain Z

User Group 1

User Group 2

domains=“(topic A) (topic Y-d) (topic Z-d)”

domains=“(topic A) (topic B) (topic K-c) (topic Z-d)”

Page 11: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 11

Vocabulary is Modular• DITA vocabulary defined as an extensible set of

modules– Map types, topic types, domains (mix-in)

• Modules are invariant for a given version in time

• A unique set of modules defines a unique “DITA document type”– Specified by @domains attribute on root element:

domains=“(topic concept) (topic hi-d)”

Page 12: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 12

All Modification is By Imposed Configuration

• Modules are “integrated” into a “document type shell”

• Integration depends on use of grammar’s parameterization features

• Can add constraints that further adjust (constrain) content models and attributes

• Logically, integration extends content models, constraint restricts them.

Page 13: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 13

Modular Vocabulary Requirements• Provide the @domains attribute contribution for the

module• Parameterize content models:– Redefine the content model in its entirety– Allow additional element types where any given element

type is allowed (mix-in of domains)• Parameterize attribute lists:– Redefine the attribute list in its entirety– Extend the attribute list with global attributes

• Provide common reusable content model fragments

Page 14: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 15

CHALLENGES WITH DITA VOCABULARY GRAMMARS

Page 15: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 16

Challenges Posed by DTD Syntax

• Need two files for each topic type or domain• Syntax is cryptic• Syntax is difficult to debug• Lots of opportunities for error• Few convenient tools for operating on DTDs as

structured data• Simple task of creating document type shells is

hard, even for experts

Page 16: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 17

Challenges Posed by XML Schema

• The XSD redefine facility• Limits on redefine• Domain integration declarations• Verbosity of the markup due to class/element

distinction

Page 17: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 18

XSD Redefine: Thank You For Playing

• Seriously over-constrained• Ambiguous definition in the XSD 1.0 spec• Incompatible implementations (maybe)• Deprecated in XSD 1.1• Resulting XSD structures very different in

pattern from original DTD or RNG models• Result: DITA 1.1 and 1.2 XSDs are not generally

constrainable

Page 18: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 19

Particle Preservation Constraint: Why?

• When redefining a content model, must preserve all particles

• For sequence groups, mean you can’t simply omit a member of the sequence via redefine:– Original: A, B?, C– Desired redefinition: A, C– No can do: particle B must be represented

• Solution:– Refactor as a sequence of choice groups– Can redefine any group to be empty

Page 19: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 20

XSD Override: Need Implementations

• The XSD 1.1 Override feature should be exactly what DITA needs

• Not yet implemented widely enough• Thus, can’t use for DITA 1.3• However, as DITA 1.3 XSDs are generated,

could implement it at any time it becomes appropriate to do so

Page 20: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 21

RELAX NG Makes Everything Better

• Syntax and semantics match very well to DITA patterns and practice

• Patterns can unilaterally extend other patterns– Matches perfectly to DITA domain extension– Makes domains “self integrating”

• Document type shells become simple inclusion lists (almost)

• XML syntax makes processing practical, if not easy

Page 21: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 22

Requirements Beyond base RELAX NG

• RELAX NG DTD Compatibility – DITA relies on defaulted attributes (@class,

@domains)• DITA-specific module metadata to enable DTD

and XSD generation

Page 22: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 23

Areas for RELAX NG Improvement

• Requirements for attributes of type @ID require special declarations in DITA shells

• No way to automatically compose attribute values– No equivalent to general internal text entities

within attribute default declarations– Required by @domain attribute in document type

shells

Page 23: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 24

COMPARISON OF DOCUMENT TYPE SHELLS

Page 24: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 25

DTD Shell<!-- ============================================================= --><!-- TOPIC ENTITY DECLARATIONS --><!-- ============================================================= -->

<!ENTITY % concept-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Concept//EN" "concept.ent">%concept-dec;

<!-- ============================================================= --><!-- DOMAIN ENTITY DECLARATIONS --><!-- ============================================================= -->

<!ENTITY % hi-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Highlight Domain//EN" "../../base/dtd/highlightDomain.ent">%hi-d-dec;

<!ENTITY % ut-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Utilities Domain//EN" "../../base/dtd/utilitiesDomain.ent" >%ut-d-dec;

<!ENTITY % indexing-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Indexing Domain//EN" "../../base/dtd/indexingDomain.ent" >%indexing-d-dec;

<!ENTITY % hazard-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Hazard Statement Domain//EN" "../../base/dtd/hazardstatementDomain.ent">%hazard-d-dec;

<!ENTITY % abbrev-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Abbreviated Form Domain//EN" "abbreviateDomain.ent">%abbrev-d-dec;

<!ENTITY % pr-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Programming Domain//EN" "programmingDomain.ent" >%pr-d-dec;

<!ENTITY % sw-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 Software Domain//EN" "softwareDomain.ent" >%sw-d-dec;

<!ENTITY % ui-d-dec PUBLIC "-//OASIS//ENTITIES DITA 1.2 User Interface Domain//EN" "uiDomain.ent" >%ui-d-dec;

<!-- ============================================================= --><!-- DOMAIN ATTRIBUTE DECLARATIONS --><!-- ============================================================= -->

<!-- ============================================================= --><!-- DOMAIN EXTENSIONS --><!-- ============================================================= --><!-- One for each extended base element, with the name of the domain(s) in which the extension was declared -->

<!ENTITY % pre "pre | %pr-d-pre; | %sw-d-pre;| %ui-d-pre; "><!ENTITY % keyword "keyword | %pr-d-keyword; | %sw-d-keyword; | %ui-d-keyword; "><!ENTITY % ph "ph | %hi-d-ph; | %pr-d-ph; | %sw-d-ph; | %ui-d-ph; "><!ENTITY % term "term | %abbrev-d-term; "><!ENTITY % fig "fig | %pr-d-fig; | %ut-d-fig; "><!ENTITY % dl "dl | %pr-d-dl; "><!ENTITY % index-base "index-base | %indexing-d-index-base; "><!ENTITY % note "note | %hazard-d-note; ">

<!-- ============================================================= --><!-- DOMAIN ATTRIBUTE EXTENSIONS --><!-- ============================================================= --><!ENTITY % props-attribute-extensions "" ><!ENTITY % base-attribute-extensions "" >

<!-- ============================================================= --><!-- TOPIC NESTING OVERRIDE --><!-- ============================================================= -->

<!-- Redefine the infotype entity to exclude other topic types and disallow nesting --><!ENTITY % concept-info-types "concept" >

<!-- ============================================================= --><!-- DOMAINS ATTRIBUTE OVERRIDE --><!-- ============================================================= --><!-- Must be declared ahead of the DTDs, which puts @domains first in order -->

<!ENTITY included-domains "&concept-att; &hi-d-att; &ut-d-att; &indexing-d-att; &hazard-d-att; &abbrev-d-att; &pr-d-att; &sw-d-att; &ui-d-att; ">

<!-- ============================================================= --><!-- TOPIC ELEMENT INTEGRATION --><!-- ============================================================= -->

<!-- Embed topic to get generic elements --><!ENTITY % topic-type PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Topic//EN" "../../base/dtd/topic.mod">%topic-type;

<!-- Embed concept to get specific elements --><!ENTITY % concept-typemod PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Concept//EN" "concept.mod">%concept-typemod;

<!-- ============================================================= --><!-- DOMAIN ELEMENT INTEGRATION --><!-- ============================================================= -->

<!ENTITY % hi-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Highlight Domain//EN" "../../base/dtd/highlightDomain.mod">%hi-d-def;

<!ENTITY % ut-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Utilities Domain//EN" "../../base/dtd/utilitiesDomain.mod">%ut-d-def;

<!ENTITY % indexing-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Indexing Domain//EN" "../../base/dtd/indexingDomain.mod">%indexing-d-def;

<!ENTITY % hazard-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Hazard Statement Domain//EN" "../../base/dtd/hazardstatementDomain.mod">%hazard-d-def;

<!ENTITY % abbrev-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Abbreviated Form Domain//EN" "abbreviateDomain.mod">%abbrev-d-def;

<!ENTITY % ui-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 User Interface Domain//EN" "uiDomain.mod">%ui-d-def;

<!ENTITY % pr-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Programming Domain//EN" "programmingDomain.mod">%pr-d-def;

<!ENTITY % sw-d-def PUBLIC "-//OASIS//ELEMENTS DITA 1.2 Software Domain//EN" "softwareDomain.mod">%sw-d-def;

<!-- ================== End DITA Concept DTD ====================

Page 25: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 26

XSD Shell<xs:schema xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"><!-- ================ TOPIC DOMAINS ===================== --> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:abbreviateDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:deliveryTargetAttDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:equationDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:hazardDomain.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:highlightDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:indexingDomain.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:markupDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:mathmlDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:programmingDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:releaseManagementDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:softwareDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:svgDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:uiDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:utilitiesDomainMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:xmlDomainMod.xsd"/>

<!-- ================ GROUP DEFINITIONS ===================== --> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:metaDeclGrp.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:tblDeclGrp.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:topicGrp.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:conceptGrp.xsd"/>

<!-- ================= MODULE INCLUDE DEFINITION ================== --> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:commonElementMod.xsd"/>

<!-- ======== Table elements ======== --> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:tblDeclMod.xsd"/>

<!-- ======= MetaData elements, plus keyword and indexterm ======= --> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:metaDeclMod.xsd"/>

<xs:redefine schemaLocation="urn:oasis:names:tc:dita:xsd:commonElementGrp.xsd"> <xs:group name="data"> <xs:choice> <xs:group ref="data"/> <xs:group ref="ut-d-data"/> </xs:choice> </xs:group> <xs:group name="foreign"> <xs:choice> <xs:group ref="foreign"/> <xs:group ref="mathml-d-foreign"/> <xs:group ref="svg-d-foreign"/> </xs:choice> </xs:group> <xs:group name="note"> <xs:choice> <xs:group ref="note"/> <xs:group ref="hazard-d-note"/> </xs:choice> </xs:group> <xs:group name="dl"> <xs:choice> <xs:group ref="dl"/> <xs:group ref="pr-d-dl"/> </xs:choice> </xs:group> <xs:group name="fig"> <xs:choice> <xs:group ref="fig"/> <xs:group ref="equation-d-fig"/> <xs:group ref="pr-d-fig"/> <xs:group ref="ut-d-fig"/> </xs:choice> </xs:group> <xs:group name="pre"> <xs:choice> <xs:group ref="pre"/> <xs:group ref="pr-d-pre"/> <xs:group ref="sw-d-pre"/> <xs:group ref="ui-d-pre"/> </xs:choice> </xs:group> <xs:group name="div"> <xs:choice> <xs:group ref="div"/> <xs:group ref="equation-d-div"/> </xs:choice> </xs:group> <xs:group name="keyword"> <xs:choice> <xs:group ref="keyword"/> <xs:group ref="markup-d-keyword"/> <xs:group ref="pr-d-keyword"/> <xs:group ref="sw-d-keyword"/> <xs:group ref="ui-d-keyword"/> <xs:group ref="xml-d-keyword"/> </xs:choice> </xs:group> <xs:group name="term"> <xs:choice> <xs:group ref="term"/> <xs:group ref="abbrev-d-term"/> </xs:choice> </xs:group> <xs:group name="ph"> <xs:choice> <xs:group ref="ph"/> <xs:group ref="equation-d-ph"/> <xs:group ref="hi-d-ph"/> <xs:group ref="pr-d-ph"/> <xs:group ref="sw-d-ph"/> <xs:group ref="ui-d-ph"/> </xs:choice> </xs:group> <xs:group name="index-base"> <xs:choice> <xs:group ref="index-base"/> <xs:group ref="indexing-d-index-base"/> </xs:choice> </xs:group> <xs:attributeGroup name="props-attribute-extensions"> <xs:attributeGroup ref="props-attribute-extensions"/> <xs:attributeGroup ref="deliveryTargetAtt-d-attribute"/> </xs:attributeGroup> </xs:redefine> <xs:redefine schemaLocation="urn:oasis:names:tc:dita:xsd:metaDeclGrp.xsd"> <xs:group name="metadata"> <xs:choice> <xs:group ref="metadata"/> <xs:group ref="relmgmt-d-metadata"/> </xs:choice> </xs:group> </xs:redefine>

<xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:topicMod.xsd"/> <xs:include schemaLocation="urn:oasis:names:tc:dita:xsd:conceptMod.xsd"/>

<!-- ================ INFO-TYPES DEFINITION ===================== --> <xs:group name="info-types"> <xs:sequence/> </xs:group>

<xs:attributeGroup name="domains-att"> <xs:attribute name="domains" type="xs:string" default="(topic abbrev-d) (topic concept) (topic equation-d) (topic hazard-d) (topic hi-d) (topic indexing-d) (topic markup-d xml-d) (topic markup-d) (topic mathml-d) (topic pr-d) (topic relmgmt-d) (topic svg-d) (topic sw-d) (topic topic) (topic ui-d) (topic ut-d) a(props deliveryTarget)"/> </xs:attributeGroup></xs:schema>

Page 26: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 27

RELAX NG Shell

Contrext, LLC

<moduleMetadata> <moduleType>topicshell</moduleType> <moduleShortName>concept</moduleShortName> <shellPublicIds> <dtdShell>-//OASIS//DTD DITA<var presep=" " name="ditaver"/> Concept//EN</dtdShell> <rncShell>urn:oasis:names:tc:dita:rnc:concept.rnc<var presep=":" name="ditaver"/></rncShell> <rngShell>urn:oasis:names:tc:dita:rng:concept.rng<var presep=":" name="ditaver"/></rngShell> <xsdShell>urn:oasis:names:tc:dita:xsd:concept.xsd<var presep=":" name="ditaver"/></xsdShell> </shellPublicIds> </moduleMetadata> </moduleDesc>

<div> <a:documentation>ROOT ELEMENT DECLARATION</a:documentation> <start> <ref name="concept.element"/> </start> </div> <div> <a:documentation>DOMAINS ATTRIBUTE</a:documentation> <define name="domains-att" combine="interleave"> <optional> <attribute name="domains" a:defaultValue="(topic abbrev-d) (topic concept) (topic equation-d) (topic hazard-d) (topic hi-d) (topic indexing-d) (topic markup-d xml-d) (topic markup-d) (topic mathml-d) (topic pr-d) (topic relmgmt-d) (topic svg-d) (topic sw-d) (topic topic) (topic ui-d) (topic ut-d) a(props deliveryTarget)" /> </optional> </define> </div> <div> <a:documentation>MODULE INCLUSIONS</a:documentation> <include href="../../base/rng/topicMod.rng"/> <include href="conceptMod.rng"> <define name="concept-info-types"> <ref name="concept.element"/> </define> </include>

<include href="abbreviateDomainMod.rng"/> <include href="../../base/rng/deliveryTargetAttDomainMod.rng" dita:since="1.3"/> <include href="equationDomainMod.rng" dita:since="1.3"/> <include href="../../base/rng/hazardstatementDomainMod.rng"/> <include href="../../base/rng/highlightDomainMod.rng"/> <include href="../../base/rng/indexingDomainMod.rng"/> <include href="markupDomainMod.rng" dita:since="1.3"/> <include href="mathmlDomainMod.rng" dita:since="1.3"/> <include href="programmingDomainMod.rng"/> <include href="releaseManagementDomainMod.rng" dita:since="1.3"/> <include href="softwareDomainMod.rng"/> <include href="svgDomainMod.rng" dita:since="1.3"/> <include href="uiDomainMod.rng"/> <include href="../../base/rng/utilitiesDomainMod.rng"/> <include href="xmlDomainMod.rng"/> </div> <div> <a:documentation>ID-DEFINING-ELEMENT OVERRIDES</a:documentation> <define name="any"> <zeroOrMore> <choice> <ref name="idElements"/> <element> <anyName> <except> <name>concept</name> <name>topic</name> <nsName ns="http://www.w3.org/2000/svg"/> <nsName ns="http://www.w3.org/1998/Math/MathML"/> </except> </anyName> <zeroOrMore> <attribute> <anyName/> </attribute> </zeroOrMore> <ref name="any"/> </element> <text/> </choice> </zeroOrMore> </define> </div></grammar>

Page 27: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 28

CONCLUSIONS AND FURTHER WORK

Page 28: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 29

Conclusions• RELAX NG: – Avoids issues with DTDs and XSDs– Preserves general knowledge of DITA coding patterns– Makes simple things as simple as they could be

(document type shell creation)– Has (almost) all the parameterization features required

• Possible to generate conforming DITA DTDs and XSDs• Can now have a single master definition of all DITA

vocabulary

Page 29: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 30

Further Work• Propose enhancement to RELAX NG to relax

ID-type attribute rules• Propose enhancement to RELAX NG DTD

compatibility to allow composition of default attribute values

• Research: Can constrainable XSD content models be generated in a general way?

Page 30: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 31

The Future

Page 31: RELAX NG and DITA: An Almost Perfect Match

05/03/2023 Contrext, LLC 32

Resources• RELAX NG specifications: http://relaxng.org• DITA 1.3 spec: http:

//tools.oasis-open.org/version-control/svn/dita/spec/

• DITA RELAX NG conversion tools: http://tools.oasis-open.org/version-control/svn/dita/doctypes/tools/relaxng/

• Me: [email protected], http://contrext.com