Next: , Previous: , Up: Records   [Contents]


2.2 Record Header

Figure 2.2 showed how two rectangle records of type Rect may be described using raw xs:integers. In a language like C, which operates directly on blocks of memory that acquire meaning only through interpretation, that raw representation would make sense: we would interpret it however we please without sprinkling our own metadata into the sequence. That is not the approach we will be taking here, as it disallows certain desirable features discussed in the Record Design Considerations, such as the ability to match on records using templates —we can only do so if such metadata were a part of the sequence itself. That approach would also place the entire onus of interpretation on the caller; this does not fit well with the philosophy of XSLT which uses pattern matching to process data.

(..., |Rect:2|,
        |A:Point:2|, 0, 1,
        |B:Point:2|, 1, 0,
      |Rect:2|,
        |A:Point:2|, 2, 2,
        |B:Point:2|, 4, 0, ...)

Figure 2.3: Delimiting records with headers

Figure 2.3 delimits the record data of Figure 2.2 by adding headers describing the type of the record and the number of fields that it contains. Newlines are added to emphasize the relationship between fields.

Note how the length of the Rect records describes the number of Points it contains, not the number of XSLT items. This distinction is of great importance if we are to allow generic data in any record field. Each record is allocated a predetermined number of slots, each of which may contain zero or more XSLT items depending on how the datum is interpreted. Each slot is identified by a 1-based index. A field is the name of a slot. In Figure 2.3, Rect has two fields —A assigned to slot 1, and B assigned to slot 2 —both of which are Points.

variable: xs:anyURI R:ns ()

xmlns:R="http://mikegerwitz.com/hoxsl/record"

The namespace to which all records elements are assigned.

Definition:

<variable name="R:ns"  as="xs:anyURI"  select="resolve-uri( 'http://mikegerwitz.com/hoxsl/record' )" />
variable: xs:anyURI _R:ns ()

xmlns:_R="http://mikegerwitz.com/hoxsl/record/_priv"

The namespace for all encapsulated record data.

Definition:

<variable name="_R:ns"  as="xs:anyURI"  select="resolve-uri( 'http://mikegerwitz.com/hoxsl/record/_priv' )" />
variable: xs:anyURI _Rs:ns ()

xmlns:_Rs="http://mikegerwitz.com/hoxsl/record/_priv/slots"

The namespace for all slot name-index mappings.

Definition:

<variable name="_Rs:ns"  as="xs:anyURI"  select="resolve-uri( 'http://www.lovullo.com/hoxsl/record/_priv/slots' )" />
variable: xs:QName R:qname ()

xmlns:R="http://mikegerwitz.com/hoxsl/record"

QName of the record header element.

Definition:

<variable name="R:qname"  as="xs:QName"  select="QName( $R:ns, 'R:Record' )" />
function: element( R:Record ) R:make-record-header (slots as xs:integer)

xmlns:R="http://mikegerwitz.com/hoxsl/record"

Make a new anonymous record header containing slots slots.

Usually, you want a record to be named, but anonymous records might be useful for temporary or grouped data.

Definition:

<function name="R:make-record-header"  as="element( R:Record )">
  <param name="slots"  as="xs:integer" />

  <sequence select="R:make-record-header( $R:qname, $slots, () )" />
</function>
function: element( R:Record ) R:make-record-header (qname as xs:QName, slots as xs:integer)

xmlns:R="http://mikegerwitz.com/hoxsl/record"

Make a new record header for a record identified by qname containing slots slots.

N.B.: This does not provide any field names or values —this header should not be used directly within a sequence unless the caller is expecting it, since it will otherwise consume adjacent sequence items when used with the Hoxsl record APIs.

Definition:

<function name="R:make-record-header"  as="element( R:Record )">
  <param name="qname"  as="xs:QName" />
  <param name="slots"  as="xs:integer" />

  <sequence select="R:make-record-header( $qname, $slots, () )" />
</function>
function: element( R:Record ) R:make-record-header (qname as xs:QName, slots as xs:integer, Supertype as element( R:Record )?)

xmlns:R="http://mikegerwitz.com/hoxsl/record"

Make a new record header for a record identified by qname containing slots slots. The record will be a subtype of supertype.

N.B.: This does not provide any field names or values —this header should not be used directly within a sequence unless the caller is expecting it, since it will otherwise consume adjacent sequence items when used with the Hoxsl record APIs.

See R:is-a#2.

Definition:

<function name="R:make-record-header"  as="element( R:Record )">
  <param name="qname"  as="xs:QName" />
  <param name="slots"  as="xs:integer" />
  <param name="Supertype"  as="element( R:Record )?" />

  <variable name="super-slots"  as="xs:integer"  select="if ( $Supertype ) then R:slot-count( $Supertype ) else 0" />

  <variable name="slot-count"  as="xs:integer"  select="max( ( $slots, $super-slots ) )" />

  <sequence select="n:element( $R:qname, ( n:attr( QName( $_R:ns, 'slots' ), $slot-count ) ), ( n:element( QName( $_R:ns, '_R:slot-names' ) ), n:element( QName( $_R:ns, '_R:types' ), (), ( $Supertype/_R:types/node(), n:element( $qname ) ) ) ) )" />
</function>

R:make-record-header#2 provides the most generic definition of a record possible. All records are identifiable by a R:Record header node, containing also the number of slots that the record will consume. Notice that these slots are not provided names —this is unnecessary for their use.

Within the R:Record node is a node identified by the provided qname, which provides record typing (see R:make-record-header#3). A supertype may optionally be provided to produce type hierarchies—all records are of type R:Record, but could be be further subtyped for particular applications and used polymorphically.2 See Record Polymorphism.

An accessor function is provided to retrieve the slot count of a record; this should always be used, as the record implementation could change in the future:

function: xs:integer R:slot-count (Record as element( R:Record ))

xmlns:R="http://mikegerwitz.com/hoxsl/record"

Determine the number of slots available in the record Record.

Definition:

<function name="R:slot-count"  as="xs:integer">
  <param name="Record"  as="element( R:Record )" />

  <sequence select="$Record/@_R:slots" />
</function>

Footnotes

(2)

Consider how subtyping might be performed: rather than creating a new record header listing all parent types, it would be useful to be able to reference an existing record header, which would in turn implicitly reference each of its supertypes.


Next: , Previous: , Up: Records   [Contents]