Common Lisp Package: XPATH-SYS

The XPATH-SYS package provides an API for extensions to Plexippus XPath. @begin[Pipes]{section} Pipes are lazy lists, inspired by their implementation in Norvig's 'Paradigms of Artificial Intelligence Programming'. @aboutmacro{make-pipe} @aboutfun{pipe-head} @aboutfun{pipe-tail} @end{section} @begin[Node sets]{section} Node sets are the XPath data type used to represent the results of evaluations that select multiple nodes. As sets, they never contain duplicates. Conceptually, they are unordered, with the most important order defined on them being the document order. As a data structure though, node sets are backed by a pipe, and the order of elements in that pipe is well-documented: By default, the pipe of returned node sets is sorted into document order. When unordered results are requested, the order is usually not specified, but in some cases, are already sorted according to the axis being queried, which is usually sorted either in document order,or in reverse document order. See @fun{xpath:evaluate} for the @code{unordered} argument. @aboutclass{node-set} @aboutfun{make-node-set} @aboutfun{pipe-of} @end{section} @begin[Implementing environments]{section} Environments provide compilation-time configuration for XPath. An environment is a CLOS object, which is queried by the compiler using generic functions that users can implement on their own subclasses of @class{xpath::environment}. The default environment class implements a `dynamic' environment, backed by information bound in dynamic variables, so that typical uses of XPath work without special environment classes. @aboutfun{environment-find-namespace} @aboutfun{environment-find-variable} @aboutfun{environment-find-function} @end{section} @begin[Defining extension functions]{section} XPath defines built-in functions in the empty namespace. Using the extension API, user code can implement XPath functions addressed using other namespaces. @aboutmacro{define-extension} @aboutmacro{define-xpath-function/lazy} @aboutmacro{define-xpath-function/eager} @aboutmacro{define-xpath-function/single-type} @aboutfun{find-xpath-function} @end{section} @begin[Profiling support]{section} The profiling facility records the run time of XPath evaluations and pattern matching. @aboutfun{enable-profiling} @aboutfun{disable-profiling} @aboutfun{report} @end{section} @begin[Miscellaneous functions]{section} Other useful functions: @aboutfun{get-node-id} @end{section}

README:

FUNCTION

Public

DISABLE-PROFILING

@return{nil} @short{Disables profiling.} Disables profiling for future XPath compilations, but keeps recorded profiling samples for @fun{report}. Previously returned closures that were created with profiling enabled will not record samples until profiling is re-activated. @see{enable-profiling}

ENABLE-PROFILING (&OPTIONAL (VERBOSEP T))

@return{nil} @short{Enables profiling.} Resets any existing profile samples and enables profiling for future XPath compilations. Previously returned closures that were created with profiling disabled are not affected by this setting, but closures created during an earlier profiling session will start sampling again. But note that @fun{evaluate}, @fun{node-matches-p}, and @fun{pattern-case} will recompile their cached closure when this setting has changed. Profiling is not thread safe. @see{disable-profiling} @see{report}

FIND-XPATH-FUNCTION (LOCAL-NAME URI)

@arg[local-name]{local part of the function name} @arg[uri]{namespace URI of the function} @return[uri]{an XPath function object} @short{Performs an XPath function lookup using standard lookup rules} All defined extensions for the namespace specified by @code{uri} are scanned for function with specified @code{local-name}.

GET-NODE-ID (NODE-OR-NODE-SET)

@arg[node-or-node-set]{a @class{node-set} or a single XML node} @return{an alphanumeric string} @short{Generates an unique identifier for the first node @code{node-set} (or, if a node is specified, for that node).} This function is similar to the generate-id() XSLT function, but its results are unique only within its document, whereas XSLT also prepends an ID designating the document.

MAKE-NODE-SET (PIPE &OPTIONAL (ORDERING UNORDERED))

@arg[pipe]{a pipe} @arg[ordering]{one of :document-order, :reverse-document-order, :unordered} @return{a @class{node-set}} Makes a @class{node-set} containing nodes from the @code{pipe} with specified @code{ordering}.

PIPE-HEAD (PIPE)

@arg[pipe]{a pipe} @return{an object} Returns the head of the @code{pipe}.

PIPE-OF (NODE-SET)

@arg[node-set]{a @class{node-set}} @return{a pipe} Returns the pipe that contains the elements of the @code{node-set}.

SETFPIPE-OF (PIPE NODE-SET)

@arg[pipe]{a pipe} @arg[node-set]{a @class{node-set}} @return{the value of @code{pipe}} Sets the pipe that contains the element sof the @code{node-set}.

PIPE-TAIL (PIPE)

@arg[pipe]{a pipe} @return{an object} @short{Returns the tail of the list.} First time @code{pipe-tail} is called it causes pipe tail expression to be evaluated and remembered for later calls.

REPORT (&KEY (GROUP-IDENTICAL-EXPRESSIONS T))

@arg[group-identical-expressions]{Boolean, indicates whether times recorded for closures that were compiled separately, but for the same expression, are to be summed together. Default is T.} @short{Shows profiling output.} Shows cumulative run time and real time, number of calls, and average run time for each XPath expression or XPattern matcher that was invoked. @see{enable-profiling} @see{disable-profiling}

MACRO

Public

DEFINE-EXTENSION (NAME URI &OPTIONAL DOCUMENTATION)

@arg[name]{the name of XPath extension (a symbol)} @arg[uri]{URI corresponding to XPath extension (a string)} @arg[documentation]{documentation string for the XPath extension} @short{Defines an XPath extension with specified @code{name} and @code{uri}.} An XPath extension is a collection of XPath functions that are defined using one of @fun{define-xpath-function/lazy}, @fun{define-xpath-function/eager} or @fun{define-xpath-function/single-type} macros. In order to use the extension, one must bind a prefix string to its @code{uri} using @fun{with-namespaces} macro. Example: @begin{pre} (defparameter *my-namespace* "http://example.net/my-xpath-extension") (xpath-sys:define-extension my-ext *my-namespace* "My Extension") (xpath-sys:define-xpath-function/single-type my-ext add-quotes string (string) (concat "\"" string "\"")) (defun get-my-quoted-string(doc) (with-namespaces (("my" *my-namespace*)) (evaluate "add-quotes(//some-element)" doc))) @end{pre}

DEFINE-XPATH-FUNCTION/EAGER (EXT NAME ARGS &BODY BODY)

@arg[ext]{name of an XPath extension (a symbol)} @arg[name]{XPath function name} @arg[args]{XPath function arguments} @short{Defines an XPath function, "eager" style.} The @code{body} is evaluated during evaluation of XPath expressions each time the function being defined is called. It's passed a list of values corresponding to XPath function arguments and should return a value of one of XPath types (string, boolean, number, node set). Example: @begin{pre} (define-xpath-function/eager my-ext join (delim node-set) (reduce (lambda (a b) (concatenate 'string a delim b)) (map-node-set->list #'string-value node-set))) @end{pre} @see{define-xpath-extension} @see{define-xpath-function/lazy} @see{define-xpath-function/single-type}

DEFINE-XPATH-FUNCTION/LAZY (EXT NAME ARGS &BODY BODY)

@arg[ext]{name of an XPath extension (a symbol)} @arg[name]{XPath function name} @arg[args]{XPath function arguments} @short{Defines an XPath function, "lazy" style.} The @code{body} is evaluated during compilation of XPath expressions each time the function being defined is referenced. It's passed a list of "thunks" corresponding to XPath function arguments and should return a new "thunk". A "thunk" is a function that takes an XPath @class{context} as argument and returns value of one of XPath types (string, boolean, number, node set). Example: @begin{pre} (define-xpath-function/lazy my-ext my-if (v if-part else-part) #'(lambda (ctx) (if (boolean-value (funcall v ctx)) (funcall if-part ctx) (funcall else-part ctx)))) @end{pre} @see{define-xpath-extension} @see{define-xpath-function/eager} @see{define-xpath-function/single-type}

DEFINE-XPATH-FUNCTION/SINGLE-TYPE (EXT NAME TYPE ARGS &BODY BODY)

@arg[ext]{name of an XPath extension (a symbol)} @arg[name]{XPath function name} @arg[args]{XPath function arguments} @short{Defines an XPath function, "eager" style with automatic type conversion.} The @code{body} is evaluated during evaluation of XPath expressions each time the function being defined is called. It's passed a list of values corresponding to XPath function arguments and should return a value of one of XPath types (string, boolean, number, node set). Argument values are automatically converted to specified XPath @code{type}. Example: @begin{pre} (xpath-sys:define-xpath-function/single-type my-ext add-quotes string (string) (concat "\"" string "\"")) @end{pre} @see{define-xpath-extension} @see{define-xpath-function/lazy} @see{define-xpath-function/eager}

MAKE-PIPE (HEAD TAIL)

@arg[head]{pipe head (evaluated)} @arg[tail]{tail expression} @return{a pipe} @short{Constructs a pipe (lazy list).} The @code{head} expression is evaluated immediatelly. The value of @code{head} will be returned by @fun{pipe-head} called for the pipe object returned by @code{make-pipe}. Evaluation of @code{tail} expression is delayed until @fun{pipe-tail} is called for the pipe returned by this function. Evaluation of @code{tail} expression should produce a pipe or a list.

Private

Undocumented

DEFINE-DEFAULT-METHOD (NAME (&REST ARGS) &BODY BODY)

GENERIC-FUNCTION

Public

ENVIRONMENT-FIND-FUNCTION (ENVIRONMENT LOCAL-NAME URI)

@arg[environment]{an XPath environment object} @arg[local-name]{local part of expanded-name of the function} @arg[uri]{namespace URI of the function} @return{an XPath function or nil if it cannot be found} @short{Finds an XPath function by @code{local-name} and @code{uri}}. XPath function is a Lisp function that takes zero or more "thunks" as its arguments (corresponding to XPath expressions passed as function arguments) and returns a new "thunk". A "thunk" is a function that takes an instance of @class{context} as its argument and returns the value of one of XPath types.

ENVIRONMENT-FIND-NAMESPACE (ENVIRONMENT PREFIX)

@arg[environment]{an XPath environment object} @arg[prefix]{prefix part of a QName} Returns namespace URI for specified @code{prefix}.

ENVIRONMENT-FIND-VARIABLE (ENVIRONMENT LOCAL-NAME URI)

@arg[environment]{an XPath environment object} @arg[local-name]{local part of expanded-name of the function} @arg[uri]{namespace URI of the function} @return{XPath variable "thunk"} @short{Finds an XPath variable by @code{local-name} and @code{uri}}. XPath variable is represented by a "thunk". A "thunk" is a function that takes an instance of @class{context} as its argument and returns the value of one of XPath types.