OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help

dita message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]

Subject: Re: [dita] Refinement of XSD Constraint Specifications

In working on the Machine Industry taskbody constraint, I have confirmed
that there are still limitations with what you can do with xs:redefine
that will require additional levels of groups.

In particular:

1. It is not possible to directly redefine a domain entity integration
group such that the base element type is not allowed. This is because when
you use xs:redefine to add element types to a group you must also
reference the original group and it has the effective occurrence value of
"1" for min and max occurs.

For example, given this base definition of the prereq group from

<xs:group name="prereq">
      <xs:element ref="prereq" minOccurs="0"/>

The redefinition for integrating the taskreq domain would be:

<xs:group name="prereq">
    <xs:group ref="prereq"/>
    <xs:group ref="taskreq-d-prereq" />

This then allows the members of the taskreq-d-prereq group to occur
wherever <prereq> is allowed.

However, you cannot omit the reference to the "prereq" group or set it's
occurrence to something other than 1, per the rules of xs:redefine.

Given that, I don't see any easy way (or perhaps, any way) to that kind of
constraint using XSD.

If this did work, it would allow the Machinery Industry taskbody
constraint to be implemented in a direct way since the effect of the
constraint as currently defined is identical to simply disallowing any use
of <prereq> or <postreq> while integrating the taskreq domain (because
<prereq> and <postreq> only occur in the task body, so disallowing them
anywhere has the effect of not allowing them only in taskbody).

While it is possible to directly redefine the taskbody content model, it
is not possible to, at the same time, also allow a new element type
(prelreqs and closereqs), because in that case there is not a one-to-one
correspondence between the particles in the original group and the
particles in the redefined group.

Thus, while it's not required for the strict taskbody constraint, the
additional levels of grouping within the XSD version of the taskbody are
required in order to implement the Machinery Industry constraint. So that
answers my earlier question about needing to retain this particular
construct: yes, it's required by the Machinery Industry constraint.

While Eric had early on determined that substitution groups would not work
for DITA, I did a little experimentation to convince myself of that as
well, and I did. At a minimum, substitution requires that if the
substitution head (what we would call the base type) is mixed, then all
elements in the substitution group must also allow mixed content and this
is clearly not acceptable for DITA.

So that pretty much brings us back to where we were before: for certain
XSD constraint use cases, there is no option but to modify the content
models to allow the redefinition required. However, unmodified content
models are constrainable as long as the constraint is only making things
either disallowed or otherwise reducing the base cardinality or making the
optional required. But any case where you must both disallow and extend
(the Machine Industry case) cannot be done with the content models as
directly produced from the RELAX NG.



Eliot Kimber, Owner
Contrext, LLC

On 8/25/14, 10:56 AM, "Eliot Kimber" <ekimber@contrext.com> wrote:

>I presented a paper on RELAX NG and DITA at the Balisage conference and as
>part of that paper talked about the issues with XSD redefine and the
>problems it poses. Out of the discussion following my paper I learned that
>in fact the way we had been doing constraints was unnecessarily
>complicated in many cases.
>The challenge is the requirement for xs:redefine that every "particle" in
>the group being redefined be accounted for in the redefined group. Here
>"particle" means any group or element reference, distinct sequence or
>group wrapper, etc.
>This causes a problem when you want to omit something (which is usually
>what constraints are doing) because you can't simply redefine the group
>and leave out the things you don't want when the group is a sequence (the
>way you can with DTDs and RELAX NGs).
>Eric's solution to this was to use a pattern of intermediate groups, where
>each intermediate group is defined in such a way that you can just leave
>things out.
>However, what I learned was that the intended way to "leave things out" is
>actually to set the maxOccurs and minOccurs values to "0", which
>effectively makes the particle (group reference) disallowed but satisfies
>the particle correspondence requirement of xs:redefine.
>This approach avoids the issue I reported earlier with sequence content
>models not being inherently constrainable. With this approach, any content
>model can be constrained simply by copying it and changing the maxOccurs
>value to "0" (the minOccurs must already be zero or it wouldn't be valid
>to constrain it away).
>Using this approach, for example, the base taskbody content model can be
>rewritten to directly match the RELAX NG model:
><xs:group name="taskbody.content">
>      <xs:sequence>
>        <xs:choice minOccurs="0" maxOccurs="unbounded">
>          <xs:group ref="context" minOccurs="0"/>
>          <xs:group ref="prereq" minOccurs="0"/>
>          <xs:group ref="section" minOccurs="0"/>
>        </xs:choice>
>        <xs:sequence>
>          <xs:choice minOccurs="0" maxOccurs="1">
>            <xs:group ref="steps"/>
>            <xs:group ref="steps-unordered"/>
>            <xs:group ref="steps-informal"/>
>          </xs:choice>
>        </xs:sequence>
>        <xs:sequence>
>          <xs:group ref="result" minOccurs="0"/>
>          <xs:group ref="example" minOccurs="0" maxOccurs="unbounded"/>
>          <xs:group ref="postreq" minOccurs="0" maxOccurs="unbounded"/>
>        </xs:sequence>
>      </xs:sequence>
>   </xs:group>
>With this base the strict taskbody constraint can then be:
><xs:group name="taskbody.content">
>       <xs:sequence>
>         <xs:sequence>
>           <xs:choice minOccurs="0" maxOccurs="unbounded">
>             <xs:group ref="context" minOccurs="0"/>
>             <xs:group ref="prereq" minOccurs="0"/>
>             <xs:group ref="section" minOccurs="0" maxOccurs="0"/>
>           </xs:choice>
>           <xs:sequence>
>             <xs:choice minOccurs="0" maxOccurs="1">
>               <xs:group ref="steps"/>
>               <xs:group ref="steps-unordered"/>
>               <xs:group ref="steps-informal" maxOccurs="0"
>             </xs:choice>
>           </xs:sequence>
>           <xs:sequence>
>             <xs:group ref="result" minOccurs="0"/>
>             <xs:group ref="example" minOccurs="0" maxOccurs="unbounded"/>
>             <xs:group ref="postreq" minOccurs="0" maxOccurs="unbounded"/>
>           </xs:sequence>
>         </xs:sequence>
>       </xs:sequence>
>     </xs:group>
>Note the maxOccurs="0" on the reference to the section and steps-informal
>groups. This implements the constraint without the need for intermediate
>Given this new way to do constraints, should we rework the current strict
>taskbody constraint to use the method shown here or should we maintain the
>DITA 1.2 intermediate group model?
>Changing the XSD definition would break any existing constraints applied
>to that model. However, the chance of those actually existing seems
>vanishingly small.
>In any case, I propose that we update the current XSD constraint topics to
>explicitly describe this method of defining constraints.
>The other TC-defined constraint, the machinery taskbody constraint, is
>still problematic because it's both integrating a domain and then
>constraining the content model of taskbody, so it may still require two
>levels of redefine. I'm working on that now.
>Eliot Kimber, Owner
>Contrext, LLC
>To unsubscribe from this mail list, you must leave the OASIS TC that
>generates this mail.  Follow this link to all your TCs in OASIS at:

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]