Enum member isCursor

Checks whether its argument fulfills all requirements to be used as XML cursor.

The cursor is the hearth of the XML parsing chain. Every higher level component (SAX, DOM, validations) builds on top of this concept. A cursor is a logical pointer inside a stream of XML nodes. It can be queried for properties of the current node (kind, name, attributes, ...) and it can be advanced in the stream. It cannot move backwards. Any reference to the outputs of a cursor may or may not be invalidated by advancing operations.

Declaration

enum isCursor(CursorType) = is(typeof((inout int = 0) { alias S = CursorType.StringType; CursorType cursor; bool b; b = cursor.atBeginning; b = cursor.documentEnd; b = cursor.next; b = cursor.enter; cursor.exit; XMLKind kind = cursor.kind; auto s = cursor.name; s = cursor.localName; s = cursor.prefix; s = cursor.content; s = cursor.wholeContent; auto attrs = cursor.attributes; s = attrs.front.prefix; s = attrs.front.localName; s = attrs.front.name; s = attrs.front.value; } ));

Parameters

NameDescription
CursorType the type to be tested

Returns

true if CursorType satisfies the XML cursor specification here stated; false otherwise

Specification

A cursor shall support at least these methods and aliases:

  • alias StringType: the type of an output string; most methods will return instances of this type;
  • alias InputType: the type of the input which is used to feed this cursor;
  • void setSource(InputType): sets the input source for this cursor and eventual underlying components; the cursor may perform other initialization work and even consume part of the input during this operation; after (partial or complete) usage, a cursor may be reinitialized and used with another input by calling this function;
  • bool atBeginning(): returns true if the cursor has never been advanced; it is thus pointing to the node of type XMLKind.document representing the XML declaration of the document;
  • bool documentEnd(): returns true if the input has been completely consumed; if it is the case, any advancing operation will perform no action
  • the following methods can be used to query the current node properties:
    • XMLKind kind(): returns the XMLKind of the current node;
    • StringType name(): returns the qualified name of the current element or the target of the current processing instruction; the empty string in all other cases;
    • StringType localName(): returns the local name of the current element, if it has a prefix; the empty string in all other cases;
    • StringType prefix(): returns the prefix of the current element, if it has any; the empty string in all other cases;
    • auto attributes(): returns a range of all attributes defined on the current element; if the current node is a processing instruction, its data section is parsed as if it was the attributes list of an element (which is quite common); for all other node kinds, an empty range is returned. The type returned by this range front method shall at least support the following fields:
      • StringType name: the qualified name of the attribute;
      • StringType prefix: the prefix of the attribute, if it has any; the empty string otherwise;
      • StringType localName: the local name of the attribute, if it has any prefix; the empty string otherwise;
      • StringType value: the value of the attribute;
    • StringType content(): returns the text content of the current comment, text node or cdata section or the data of the current processing instruction; the empty string in all other cases;
    • StringType wholeContent(): returns the entire content of the node;
  • the following methods can be used to advance the cursor in the stream of XML nodes:
    • bool enter(): tries to advance the cursor to the first child of the current node; returns true if the operation succeeded; otherwise, if the cursor was positioned on the start tag of an element, it is now positioned on its closing tag; otherwise, the cursor did not advance;
    • bool next(): tries to advance the cursor to the next sibling of the current node; returns true if the operation succeded; otherwise (i.e. the cursor was positioned on the last child of an element) it is now positioned on the closing tag of the parent element;
    • void exit(): advances the cursor to the closing tag of the element containing the current node;

Examples

/* recursively prints the kind of each node */
void recursivePrint(CursorType)(ref CursorType cursor)
    if (isCursor!CursorType)
{
    do
    {
        // print the kind of the current node
        writeln(cursor.kind);
        // if the node has children
        if (cursor.enter)
        {
            // recursively print them
            recursivePrint(cursor);
            // back to the current level
            cursor.exit;
        }
    }
    // iterate on every sibling
    while (cursor.next)
}

Authors

Lodovico Giaretta

Copyright

Copyright Lodovico Giaretta 2016 --

License

Boost License 1.0.