Skip to content

replacing an attr that is in alternation puts replacement outside of alternation #799

@sydb

Description

@sydb

This is a bit tough to explain in prose. If you (in your customization file) replace an attribute defintion (i.e., use <attDef mode="replace">) when the base attribute being replaced is an <attDef> that is itself inside an <attList org="choice">, then the replacement attribute is defined as a normal attribute, not as an attribute in alternation with the other attributes it had been in alternation with. (My guess as to why is that the replacement code that merges your customization file with the base odd, i.e. odd2odd.xsl, fails to put the replacement <attDef> back where it came from, as it were.)

For example, two of the attributes of <relation> are in alternation with one another (removing all the contents of <attDef> for readability):

  <attList>
    <attDef ident="name"/>
    <attList org="choice">
      <attDef ident="active"/>
      <attDef ident="mutual" usage="opt"/>
    </attList>
    <attDef ident="passive" usage="opt"/>
  </attList>

The resulting schema (without the values of the attributes, because I removed them from the above) boils down to:

  attribute name { text },
  (
    attribute active { text }
    |
    attribute mutual { text }?
  ),
  attribute passive { text }?

[Note 1: This itself seems to me a bit nuts, but yes, that is how we handle relationships; there are some Schematron rules that help somewhat.]
[Note 2: Why does an empty <attDef> result in an attribute that can have any value?]

Let’s say you try to replace the @active attribute (say, in order to restrict it to one and only one teidata.pointer) from your customization file with:

    <elementSpec ident="relation" module="namesdates" mode="change">
      <attList>
        <attDef ident="active" mode="replace">
          <datatype minOccurs="1" maxOccurs="1">
            <dataRef key="teidata.pointer"/>
          </datatype>
        </attDef>
      </attList>
    </elementSpec>

then the resulting schema boils down to (with the values of the attributes, because I did not remove them this time):

   attribute active { xsd:anyURI { pattern = "\S+" } }?,
   (
     attribute mutual { list { xsd:anyURI { pattern = "\S+" }+ } }?
   ),
   attribute name { xsd:token { pattern = "[^\p{C}\p{Z}]+" } }?,
   attribute passive { list { xsd:anyURI { pattern = "\S+" }+ } }?,

which is obviously totally screwy — the @active attribute is no longer in alternation with @mutual, which is left alone to be in alternation with itself.

But this problem does not happen when you use "change" mode. E.g., if you then try the same thing but instead use mode="change" on the <attDef>, then the resulting schema boils down to:

   (
     attribute active { xsd:anyURI { pattern = "\S+" } }?
     | 
     attribute mutual { list {xsd:anyURI { pattern = "\S+" }+ } }?
   ),
   attribute name { xsd:token { pattern = "[^\p{C}\p{Z}]+" } }?,
   attribute passive { list {xsd:anyURI { pattern = "\S+" }+ } }?,

which is exactly as expected.

I consider this somewhat high priority because the definition of <dataRef> is currently broken in tei_customization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    conversion: relaxpriority: highRelatively urgent; Council should revisit routinely.resp: StylesheetsGroupIssue is suitable for the group-learning approach taken in the Stylesheets Coop Working Group.type: bugA bug report.

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions