Re: can pure ODD define an alternation of attribute patterns?
Syd Bauman <[email protected]> Thu, 23 Mar 2017 13:42:12 -0400
| Newsgroups | gmane.text.tei.general |
|---|---|
| Message-ID | <[email protected]> |
I tihnk the short answer is "no", Pure ODD can't do that. But to be honest, I haven't tried. This is in part because I know the `roma` code that handles <attList org="choice"> is broken. (See bug 144.[1]) But ODD can do this, albeit in a roundabout, hack kind of way. (And, it turns out in writing my test, I had to add a hack to the hack to get around what I presume is a bug in ODD processing.) The attached ODD is an example of a method that at best is likely to be considered controversial, at worst bad practice. But it does exactly what (I think) you want. It re-names the element <hi> to be <methodOne>, and gives it three new required attributes: attribute.1 = "pointer" | "character" | "byte_offset" | "time_in_sec" attribute.2 = anyURI nonNegInt nonNegInt int attribute.3 = anyURI nonNegInt nonNegInt int A few caveats, in no particular order: * The method used will give some people angina. * Because RELAX NG cosntructs are used directly, you do not have the advantage that the value of attribute.3 is defined as teidata.pointer when attribute.1 is "pointer"; rather, it is defined directly as anyURI. * Hack: I had to use <rng:interleave> to group the attribute definitions; for some reason when I tried <rng:group> (which is what one would naturally expect to use) `roma` converted it to an <rng:choice>. * I really doubt you can get usable XSD, and you certainly can get helpful DTD, out of this. So personally, I prefer the solution you recommended: just create a closed list for @attribute.1, and then a small Schematron rule to ensure that @attribute.2 and @attribute.3 are of the right datatype. I have thrown that into the ODD as well, renaming <emph> to be <methodTwo>, and giving it three new required attributes named "anotherAtt.1" etc. Notes ----- [1] https://github.com/TEIC/Stylesheets/issues/144 > I would like to define an alternation of patterns of up to three > attributes, where the datatype of attribute.2 and attribute.3 is uniform > and depends on the value of attribute.1. > > Something like the following (in **pseudo-markup**): > > <rng:choice> > <rng:group> "pointer", data.pointer, > data.pointer </rng:group> > <rng:group> "character", data.nonNegativeInteger, > data.nonNegativeInteger </rng:group> > <rng:group> "byte_offset", data.nonNegativeInteger, > data.nonNegativeInteger </rng:group> > <rng:group> "time_in_sec", data.integer, > data.integer </rng:group> > .... etc. > </rng:choice> > > I could do that in RNG, but can I do that in ODD as well? > > If I understand correctly, ODD expects me to list the three attDef > declarations in an <attList> for my new class, and to declare a new data > type that groups the data types that I need for attribute.2 and > attribute.3, and to make the value of attribute.1 a closed list, and > then to slam a huuuge piece of Schematron onto this (hopefully inside > this very class definition; I haven't checked that) that would attempt > to rule out unwanted sequences. > > Is my diagnosis correct? I probably wouldn't mind being wrong. > > I also admit to having a rather hazy idea of the extent of the > difference in "staticness" between listing potential patterns in an RNG > schema on the one hand, and defining them in the ODD on the other. I > mean, I am not really sure if I could <alternate> a series of > <sequence>s containing <attDef>s. Would I end up defining a single > attribute several times? Would/Should ODD allow me to do that?
T4PB.odd
(text/plain, 5.8 KB)
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="en"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:rng="http://relaxng.org/ns/structure/1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema-datatypes">
<teiHeader>
<fileDesc>
<titleStmt>
<title>Test for Piotr Banski</title>
<author xml:id="sb" ref="p:sbauman.emt">Syd Bauman</author>
</titleStmt>
<publicationStmt>
<p>Unpublished, just to be posted to TEI-L</p>
<availability>
<p>© 2017 Syd Bauman and Northeastern University Women
Writer's Project. Available via CC 4.0 BY-SA.</p>
</availability>
</publicationStmt>
<sourceDesc>
<p>No source, this ODD document is the original.</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<schemaSpec ident="T4PB" prefix="T4PB_" start="TEI div p">
<moduleRef key="tei"/>
<moduleRef key="core"/>
<moduleRef key="header"/>
<moduleRef key="textstructure" except="div1 div2 div3 div4 div5 div6 div7"/>
<macroSpec ident="att1ptr" mode="add">
<content>
<rng:interleave>
<rng:attribute name="attribute.1">
<rng:value type="token">pointer</rng:value>
</rng:attribute>
<rng:attribute name="attribute.2">
<rng:data type="anyURI"/>
</rng:attribute>
<rng:attribute name="attribute.3">
<rng:data type="anyURI"/>
</rng:attribute>
</rng:interleave>
</content>
</macroSpec>
<macroSpec ident="att1char" mode="add">
<content>
<rng:interleave>
<rng:attribute name="attribute.1">
<rng:value type="token">character</rng:value>
</rng:attribute>
<rng:attribute name="attribute.2">
<rng:data type="nonNegativeInteger"/>
</rng:attribute>
<rng:attribute name="attribute.3">
<rng:data type="nonNegativeInteger"/>
</rng:attribute>
</rng:interleave>
</content>
</macroSpec>
<macroSpec ident="att1offset" mode="add">
<content>
<rng:interleave>
<rng:attribute name="attribute.1">
<rng:value type="token">byte_offset</rng:value>
</rng:attribute>
<rng:attribute name="attribute.2">
<rng:data type="nonNegativeInteger"/>
</rng:attribute>
<rng:attribute name="attribute.3">
<rng:data type="nonNegativeInteger"/>
</rng:attribute>
</rng:interleave>
</content>
</macroSpec>
<macroSpec ident="att1seconds" mode="add">
<content>
<rng:interleave>
<rng:attribute name="attribute.1">
<rng:value type="token">time_in_sec</rng:value>
</rng:attribute>
<rng:attribute name="attribute.2">
<rng:data type="integer"/>
</rng:attribute>
<rng:attribute name="attribute.3">
<rng:data type="integer"/>
</rng:attribute>
</rng:interleave>
</content>
</macroSpec>
<elementSpec ident="hi" mode="change">
<altIdent>methodOne</altIdent>
<content>
<alternate minOccurs="1" maxOccurs="1">
<macroRef key="att1ptr"/>
<macroRef key="att1char"/>
<macroRef key="att1offset"/>
<macroRef key="att1seconds"/>
</alternate>
<macroRef key="macro.paraContent"/>
</content>
<remarks>
<p>The attributes on this element ...</p>
</remarks>
</elementSpec>
<!-- above is ODD hack; below is PureODD with Schematron -->
<classSpec ident="att.aPureODDmethod" type="atts" mode="add">
<constraintSpec scheme="schematron" ident="two-and-three-match-one">
<constraint>
<sch:rule context="*[@anotherAtt.1 eq 'pointer']">
<sch:assert test="@anotherAtt.2 castable as xsd:anyURI">when @anotherAtt.1 is 'poitner' @anotherAtt.2 must be a URI</sch:assert>
<sch:assert test="@anotherAtt.3 castable as xsd:anyURI">when @anotherAtt.1 is 'poitner' @anotherAtt.3 must be a URI</sch:assert>
</sch:rule>
<sch:rule context="*[@anotherAtt.1 = ('character','byte_offset')]">
<sch:assert test="@anotherAtt.2 castable as xsd:nonNegativeInteger">when @anotherAtt.1 is '<sch:value-of select="@anotherAtt.1"/>' @anotherAtt.2 must be a counting number</sch:assert>
<sch:assert test="@anotherAtt.3 castable as xsd:nonNegativeInteger">when @anotherAtt.1 is '<sch:value-of select="@anotherAtt.1"/>' @anotherAtt.3 must be a counting number</sch:assert>
</sch:rule>
<sch:rule context="*[@anotherAtt.1 eq 'time_in_sec']">
<sch:assert test="@anotherAtt.2 castable as xsd:integer">when @anotherAtt.1 is 'time_in_sec' @anotherAtt.2 must be an integer</sch:assert>
<sch:assert test="@anotherAtt.3 castable as xsd:integer">when @anotherAtt.1 is 'time_in_sec' @anotherAtt.3 must be an integer</sch:assert>
</sch:rule>
</constraint>
</constraintSpec>
<attList>
<attDef ident="anotherAtt.1">
<datatype minOccurs="1" maxOccurs="1">
<dataRef key="att1types"/>
</datatype>
</attDef>
<attDef ident="anotherAtt.2">
<datatype minOccurs="1" maxOccurs="1">
<dataRef key="att23types"/>
</datatype>
</attDef>
<attDef ident="anotherAtt.3">
<datatype minOccurs="1" maxOccurs="1">
<dataRef key="att23types"/>
</datatype>
</attDef>
</attList>
</classSpec>
<dataSpec ident="att1types">
<content>
<valList type="closed">
<valItem ident="pointer"/>
<valItem ident="character"/>
<valItem ident="byte_offset"/>
<valItem ident="time_in_sec"/>
</valList>
</content>
</dataSpec>
<dataSpec ident="att23types">
<content>
<alternate>
<dataRef key="teidata.pointer"/>
<dataRef key="teidata.count"/>
<dataRef name="integer"/>
</alternate>
</content>
</dataSpec>
<elementSpec ident="q" mode="change">
<altIdent>methodTwo</altIdent>
<classes mode="change">
<memberOf key="att.aPureODDmethod"/>
</classes>
</elementSpec>
</schemaSpec>
</body>
</text>
</TEI>