[examplotron] Re: Advanced handling of attributes

From: Jonathan Lang <[email protected]>
Date: Tue Jul 08 2003 - 04:57:13 UTC

Eric van der Vlist wrote:
> Jonathan Lang wrote:
> > When applying the attribute annotations to the eg:attribute element
> > annotation, you need to restrict some of the capabilities. Assertions
> > are fine as is; they give you a way of validating the attribute's
> > value.
>
> Assertions would still be an issue since they are currently translated
> as Schematron rules and Schematron rules can't be applied to
> attributes...

I'll drop this line of research for now, and will assume that assetions
cannot be used on attributes (at least, not directly). If this changes, a
temporary hack solution would be to reference the attributes in question
using @eg:assert.

> > Doing so would require some clarification as to the uniqueness of a
> > given name in @eg:define - the idea of applying an attribute's content
> > model to an element, or vice versa, seems awkward at best; and you
> > might be better off isolating the @eg:defines that are associated with
> > attributes from the @eg:defines that are associated with elements.
>
> Yes.

It also might not be possible. RELAX NG doesn't appear to provide any
mechanism for defines that can only be referenced from within attributes.

> Another option I have been playing with would be to allow a subset of
> Relax NG compact syntax in attributes and I'd like to be as close as
> possible to the compact syntax if we allow structured annotations in
> attributes.

Note that the use of occurrence symbols that I outlined above contradicts
the Relax NG compact syntax. In Relax NG, "pattern '+'" is equivelent to
<oneOrMore>pattern</oneOrMore>; in the notation that I proposed above,
"pattern '+'" would equate to <list>pattern</list>. Meanwhile, "pattern
'*'" from Relax NG would be <zeroOrMore>pattern</zeroOrMore>, and from my
notation it would be <optional><list>pattern</list></optional>.

Note also that Relax NG assumes that attributes are required, and uses the
"pattern '?'" notation to make them optional; Examplotron, OTOH, assumes
that attributes are required; therefore, a variation from the Relax NG
compact syntax is neccessary to provide some sort of notation identifying
required attributes.

I haven't found anything in the Relax NG specification which forbids an
attribute from containing elements; nor can I find anything excluding
groups, interleaves, zeroOrMores, oneOrMores, mixeds, parentRefs, emptys,
externalRefs, or grammars from use inside attributes. Nonetheless, I
can't think of any cases where any of these would be useful in defining
the contents of a singly-named attribute (ass opposed to an attribute
which uses a nameClass). Furthermore, ref is explicitly excluded from
being used within an attribute, which puzzles me (especially since
parentRef and externalRef don't appear to be so restricted).

IMHO, a viable subset of Relax for use in the Examplotron value markup
would be: choice, optional, list, text, value, and data. The compact
syntax for these would be:

   choice ::= pattern '|' pattern
   optional ::= pattern '?'
   list ::= 'list' '{' pattern '}'
   text ::= 'text'
   value ::= datatype? literal
   data ::= datatype paramList? exclPattern?
      paramList ::= '(' param '=' literal (',' param '=' literal)? ')'
      exclPattern ::= '-' (choice | value | data)

There's also the matter of Relax NG compact syntax comments - IIRC, they
begin with ## and end with an end-of-line.

If you're willing to deviate from the Relax NG compact syntax somewhat,
you might get more pleasing results. In particular, I'm thinking of
replacing 'text' with 'eg:text' (this would give Examplotron an inherent
datatype, and would thus remove the requirement to include the XML Schema
Datatypes namespace; it would also keep to the Examplotron rule of thumb
that datatypes are QNames) or removing it entirely (text can't be used
within value or data, and it renders choice meaningless; this leaves it
useful only in conjunction with list and optional), and combining the
optional and list syntaxes into a single occurrence-like character (we can
only get away with this if zeroOrMore and oneOrMore are removed from the
syntax, freeing up appended "*" and "+" symbols for other uses; doing so
would remove the need for a 'list' keyword, and would further eliminate
the one instance of nested curly braces being used in the syntax).

I think that the following syntax would cover everything that the above
subset of Relax NG compact syntax would:

   valueMarkup ::= '{' pattern? occurrence? '}'
   pattern ::= value | data | choice
   occurrence ::= '-' | '?' | '.' | '*' | '+'
   value ::= datatype? literal
   data ::= datatype paramList? exclPattern?
   choice ::= pattern '|' choice
   datatype ::= QName
   paramList ::= '(' param '=' literal (',' param '=' literal)? ')'
   exclPattern ::= '-' pattern

If the pattern clause is absent, it would map to <text/>
A value pattern would map to <value type="{datatype}">{literal}</value>
A type pattern would map to
  <data type="{datatype}">
    <param name="{param}" eg:occurs="*">{literal}</param>
  </data>
A choice pattern would map to <choice>{pattern} {choice}</choice>
For occurrences,
   '-' would map to <ega:annotation>{pattern}</ega:annotation>
   '*' or '+' would map to <list>{pattern}</list>
   '?', '*', or absence would result in the attribute being enclosed in an
      <optional> element.

Missing are a way to define patterns to be referenced within attributes
(because Relax NG doesn't allow for references within attributes) and a
way to define default values for attributes (because default values are
part of the Relax NG compatability extension, which does not AFAIK have a
compact syntax associated with it). If I'm mistaken and refs can indeed
exist within attributes, I'd modify the valueMarkup by inserting an
optional defineClause just before the pattern, and I'd insert a choice of
NCName into pattern; if we want to allow for default values, I'd insert an
optional default clause into the valueMarkup just after the occurrence:

   valueMarkup ::= '{' define? pattern? occurrence? default? '}'
   define ::= NCName ':='
   pattern ::= value | data | choice | reference
   occurrence ::= '-' | '?' | '.' | '*' | '+'
   default ::= '=' literal
   value ::= datatype? literal
   data ::= datatype paramList? exclPattern?
   choice ::= pattern '|' choice
   reference ::= NCName
   datatype ::= QName
   paramList ::= '(' param (',' param)? ')'
   exclPattern ::= '-' pattern
   param ::= NCName '=' literal

A define would have the same effect on the attribute as @eg:define has on
   an element.
A default would map to the inclusion of
   @dtd:default={literal} in <attribute>, where
   xmlns:dtd="http://relaxng.org/ns/compatibility/annotations/1.0" (the
   Relax NG Compatability extension).

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com
Received on Tue Jul 8 06:57:16 2003

This archive was generated by hypermail 2.1.8 : Fri Dec 03 2004 - 14:29:47 UTC