current elements

built-in shelf

Purpose

At any point in the processing of an XML or SGML instance there are one or more elements open, starting with the document element. current elements gives you shelf-like access to the currently opened elements and their attributes.

current elements differs from a shelf in the following ways:

  • An element can be opened more than once, so its "name" can occur more than once in the set of opened elements. As a consequence, an element is typically identified by its relationship to other elements, such as parent, ancestor, preparent, open element, or element as well as, or instead of, its name.
  • There is not one obvious ordering of opened elements as there is for shelf items or attributes. Either the first opened or the most recently opened can reasonably be considered to be the "first" element: there are times when you will need to examine the opened elements starting with the document element, and other times starting with the most recently opened element.

name of, when applied to current element, returns the name of the element.

Since current elements can be treated like a shelf in many ways, you can use a repeat over to iterate over the shelf. The following code illustrates how a repeat over action can be used on the current elements shelf to list the currently opened elements together with each of the element's non-implied attribute values:

  repeat over current elements as this-element
     output name of current element this-element || "%n"
     repeat over attributes of current element this-element
                 as this-attribute
        do unless attribute this-attribute is implied
           output "   " ||
           key of attributes this-attribute ||
           " = %"%v(this-attribute)%"%n"
        done
     again
  again

If you want to process the opened elements in most-recently-opened-first order, you can use the reversed keyword in the repeat over loop, as follows:

  repeat over reversed current elements

An alias name must be used with repeat over current elements. The alias is used to name the element selected by each iteration over the set of currently opened elements. For example, in the following loop, "this-element" is the alias assigned to the element selected in the current iteration:

  repeat over current elements as this-element

Note that #item always begins with a value of one (1) on the first iteration and has a value equal to the number of opened elements on the last iteration, even when the reversed option is used. #item will never count down to one.

A repeat over action can iterate over the set of opened elements or a subset of them by qualifying current elements with of. A repeat over action iterates over the set of opened elements consisting of the identified element and all its ancestors. When you do not specify an element, the repeat over begins with the currently opened element.

A repeat over action that iterates over current elements buffers text written to the #markup-parser stream until the end of the loop. None of the text is passed to the parser until after the end of the repeat over action. For example, in the following, all of the currently opened elements will be closed, but only after the end of the repeat over:

  repeat over reversed current elements as this-element
  output "</" || name of current element this-element || ">"
  again

A "%q" format item, references to attributes, and element tests are not affected by a repeat over current elements action. Within the loop, all of these apply to the same element as they would outside of it. In other words, a "%q" in such a repeat over loop does not give the name of the element selected by the current iteration, but rather that of the most recently opened element.