TEIC / Stylesheets

TEI XSL Stylesheets
238 stars 126 forks source link

ODD compilation excludes model classes not explicitly included #596

Open raffazizzi opened 1 year ago

raffazizzi commented 1 year ago

Consider the following <schemaSpec>:

<schemaSpec ident="oddex1" start="TEI">
        <moduleRef key="header"/>
        <moduleRef key="core"/>
        <moduleRef key="tei"/>
        <moduleRef key="textstructure"/>
        <moduleRef key="namesdates" include="nationality"/>
</schemaSpec>

When its ODD gets compiled (e.g. via TEIGarage, which uses the Stylesheets), the definition for <nationality> will not include model.persStateLike:

<elementSpec xmlns:rng="http://relaxng.org/ns/structure/1.0" module="namesdates" ident="nationality">
<!-- ... -->
 <classes>
    <memberOf key="att.global"/>

    <memberOf key="att.datable"/>
    <memberOf key="att.editLike"/>
    <memberOf key="att.naming"/>
    <memberOf key="att.typed"/>
  </classes>
<!-- ... -->
</elementSpec>

To fix this, one can include the model explicitly with a <classRef>, but should it be included automatically?

@lb42 pointed to this passage in the Guidelines:

The Guidelines are a bit coy on the matter : "The effect of a moduleRef element is to include in the schema all declarations provided by that module. This may be modified by means of the attributes include and except which allow the encoder to supply an explicit lists of elements from the stated module which are to be included or excluded respectively." they say : but this doesnt make explicit that "This may be modified..." applies only to elements, and that ipso facto other declarations in a module (such as classes or macros) are always included.

What should be the right behavior here? This of course affects Roma, too. See https://github.com/TEIC/romajs/issues/101

raffazizzi commented 1 year ago

Follow up: it seems that even including <classRef key="model.persStateLike" /> isn't sufficient. Possibly because the model ins't used by any other element, so it gets dropped during compilation. This makes me think that the element may as well be dropped too: <nationality> itself isn't at all usable without including person, personGrp, or persona

lb42 commented 1 year ago

Precisely. If you modify the ODD to read

<moduleRef key="namesdates" include="nationality person"/>

then model.persStateLike reappears in the generated schema. So clearly the ODD compiler is being a bit cleverer than I thought: my guess is that it removes classes for which no member can be found.

raffazizzi commented 1 year ago

So clearly the ODD compiler is being a bit cleverer than I thought: my guess is that it removes classes for which no member can be found.

Yes, this can be seen in the verbose logs of teitorelaxng, for example:

[xslt] Phase 1: import model.persStateLike by moduleRef
[xslt] Phase 1: hang onto model.persStateLike

later:

[xslt] Phase 2: keep classSpec model.persStateLike

then:

[xslt] Reject unused class model.persStateLike

and finally:

[xslt] Reject unused memberOf pointing to model.persStateLike
sydb commented 1 year ago

So what do we (or at least you @raffazizzi & @lb42) think is the correct solution? Should we document the current behavior better (if you include an element but not its parents, the result probably is not what you expect), or change the current behavior (which would leave many schemas with lots of empty classes, but at least a user could add something to that class without difficulty)?

lb42 commented 1 year ago

I think the current behaviour is quite reasonable, once you understand that orphan elements (i.e. those with no possible parent) are always eliminated. The problem is that it's not very well explained. A previous version of Roma Classic included an additional "sanity check" which would alert the user to this and similar situations: might be worth thinking about including something like it in a future version.