[examplotron] Advanced handling of attributes

From: Jonathan Lang <dataweaver42@yahoo.com>
Date: Sun Jul 06 2003 - 05:47:24 UTC

To the best of my knowledge, the following is an accurate summary of what has
been done with attribute annotations to date:

<my:element assert="boolean XPath expression"
            content="one of eg:group, eg:mixed, eg:interleave,
                     an xsd:simpleType, or
                     an xsd:NCName that matches one of //@define"
            define="an xsd:NCName which is unique within //@define"
            occurs="one of -, ?, ., *, or +"/>

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. Occurrence is also fine as
is: "-" means that the element can't have an attribute of this name at all,
which is exactly as useful for attributes as it is for elements; "?" represents
an optional attribute with a single value; "." represents a required attribute
with a single value; "*" represents an optional attribute which contains a list
of values; and "+" represents a required attribute which contains a list of
values.

At first glance, Content would seem to be required to be restricted to an
xsd:simpleType; eg:group, eg:mixed, and eg:interleave are _not_ valid options
for an attribute (even implicitly; no elements within an eg:attribute element).
 But the "named content model" option _could_ be made to work with attributes,
if you allow @eg:define within an eg:attribute element. 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.

Once all of the restrictions are put into place, we have something like this
for eg:attributes:

<attribute name="{NCName}"
           assert="boolean XPath expression"
           content="an xsd:simpleType or
                    an xsd:NCName that matches one of //attribute/@define"
           define="an xsd:NCName which is unique within //attribute/@define"
           occurs="one of -, ?, ., *, or +"/>

IIRC, all of the above possibilities can be mapped to RELAX NG.

However, I find this approach, while powerful, to be an eyesore. As an
alternative, let me propose an expanded syntax for value annotations. By
"value annotation", I'm referring to the use of curly braces within the sample
value of an attribute to annotate valid value types for it.

The existing annotation is quite simple: an xsd:simpleType enclosed in curly
braces. However, that only covers a small subset of what the eg:attribute
element is capable of handling. In order to replace it, the value annotation
needs to be able to provide suitable equivelents to all four of the Examplotron
attribute annotations: assertions, content, naming, and occurrences. I propose
the following:

ValueAnnotation ::= '{' S? Naming? ContentType?
                    (Occurrence | Assertion | Occurrence S Assertion)? S? '}'
Naming ::= NCName ':' S
ContentType ::= NCName | simpleType
Occurrence ::= '-' | '?' | '.' | '*' | '+'
Assertion ::= 'where' XPathExpr

simpleType ::= QName

So:

<my:element ref="{ChildCount: xsd:integer. where count(../*::node())=.} 1"/>

would map to

<my:element>
  <eg:attribute name="ref" eg:define="ChildCount" eg:content="xsd:integer"
   eg:occurs="." eg:assert="count(../*::node())=."> 1</eg:attribute>
</my:element>

As is, the above is suitable to model attributes which would be #IMPLIED or
#REQUIRED in a DTD; there is currently no mechanism for default values or
#FIXED values. Under the <eg:attribute> model, the only solution that I can
see would be to introduce an optional 'value' attribute unique to eg:attribute:
when it's absent, eg:occurs="?" and "*" still map to #IMPLIED while "." and "+"
map to #REQUIRED; when it's present, "?" and "*" map to the default value while
"." and "+" map to #FIXED. In the value annotation shorthand, the equivelent
of a value attribute could be included by inserting it between the Occurrence
and the Assertion, and prepending it with an equal sign:

ValueAnnotation ::= '{' S? Naming? ContentType?
                    (Occurrence S? Default?
                     | S? Default? S Assertion
                     | Occurrence S? Default? S Assertion)? S? '}'
Naming ::= NCName ':' S
ContentType ::= NCName | simpleType
Occurrence ::= '-' | '?' | '.' | '*' | '+'
Default ::= '=' Value
Assertion ::= 'where' XPathExpr

<my:element
  ref="{ChildCount: xsd:integer=0 where count(../*::node())=.} 1"/>

would map to

<my:element>
  <eg:attribute name="ref" value="0" eg:define="ChildCount"
   eg:content="xsd:integer" eg:assert="count(../*::node())=."> 1</eg:attribute>
</my:element>

and would represent an element with an attribute that tells it how many child
elements it must have, defaulting to none.

Even if you find the fully-featured version to be too cumbersome, a simpler
version can substantially reduce the need for <eg:attribute>, even if it
doesn't eliminate it: if you keep the Occurrence part, you've eliminated the
need to use <eg:attribute> to handle required attributes (which is noted in the
specification as the most common use of said element annotation).

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com
Received on Sun Jul 6 07:47:47 2003

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