DPML is a declarative XML processing language that is itself XML.
It is more than a simple transform pipelining language as it allows conditional processing,
loops, sub-routines, and exception handling. It considers XML documents as the basic data
quantum and URIs as the method of addressing them. The XML processing
instructions and resolution of URI schemes are abstracted from the language so as to be fully
extensible. In this document we refer to a document containing DPML as an Instruction Document or
idoc.
The RelaxNG schema for a DPML idoc can be found here. The
XSD schema for a DPML idoc can be found here.
High Level Structure
The root element of a DPML idoc must be <idoc>. Inside the <idoc> element
we can place <seq> sequence elements nested to arbitrary depths and <instr>
instruction elements. The sequence elements are just a logical grouping and instructions
will be executed in normal document traversal order (depth-first).
An optional namespace xmlns:dpm="http://1060.org/dpm" may be used. The namespace must use the dpm: prefix, it is
not permitted to use a default namespace as this will effect literals.
Instruction <instr> elements define basic units of work to be performed on XML documents.
An instruction has a fixed structure which defines an operation that results in the update of one
document. The structure is composed of the following elements:
Reserved Elements
The following elements names have special meaning and are used to express the type and target URI's of an instruction.
type
A mandatory identifier that is registered with the system for resolving to a Universal Resource Accessor.
For more details see the Active URI Guide.
target
The document that the output from the instruction will be written to.
Targets support XPointer fragments to allow update of
part of a document. In this case the XPointer expression points at an element that
will be replaced by the operation's output.
If omitted the output of an instruction is discarded.
Standard Elements
The following element names are often adopted as a convention. Their types may be either URIs or inline literal XML documents.
operand
The document that is being operated on by the instruction.
For some instructions it may be mandatory, others optional, others ignored.
operator
The document that defines how the instruction operates.
For some instructions it may be mandatory, others optional, others ignored.
param
The document containing additional parameters to the instruction.
For some instructions it may be mandatory, others optional, others ignored.
With NetKernel SE 1.2.0, DPML supports arbitrarily named arguments on an instruction. Most accessors continue to use the standard
element names but now any element name can be used (except the reserved names). As with the standard elements, an element may contain either a URI or literal XML document. The URI or literal will be passed as a named argument to
the instruction URA, the name will be the same as the element.
Each instruction in DPML is used to generate a NetKernel active URI request. The element name is used as the argument name of a request argument.
See the active URI guide.
Data Types
Operands, operators, parameters and targets all reference documents by URIs. All conventional registered
URI schemes (file:, http:. ftp:) are usable within an idoc in addition to some internal schemes that are documented here.
this:[name]
The this: scheme is a local reference to some execution state or context for the currently executing idoc.
this:param
An idoc execution may have an optional parameter document which is passed to it from the invoker.
The parameter is read only and it is illegal to target the parameter.
this:param:[name]
An idoc execution may receive more than one named parameter. name is the name of the compound URI item that
references the parameter. this:param:param is identical to this:param.
this:response
Each execution has a single document called the response which is returned to the invoker.
This document is intially empty. Generally this:response is the target of operations, however
it is possible to read the response by using it as an operand, operator or parameter.
this:exception
See exception handling section. This document allows reading of the cannonical exception
document that is created in response to a handled execution exception.
var:[name]
This scheme allows the dynamic creation of transient variables within the execution of the idoc.
Variables are created blank at the point when they are first targeted in an instruction. They can
be read and overwritten as many times as necessary. At the end of execution the data in all
variables is lost.
CURI is an acronym for Canonical URI. It is a method of
obtaining indirection in a similar way to pointers in a programming language like C. The uri
below the curi: scheme is first
resolved and is expected to be a canonical URI document. A canonical URI document is a document
that has a root element of <uri> and its text value is an actual URI.
curi signifies to extract the uri from the canonical uri document and substitute it into the instruction. curi and a
canonical uri document can be used just like a direct URI in operand, operator, parameter, and target.
Here is an example cannonical URI document and let's say this is accessible with the URI file:/myCURI.xml:
actually copies http://www.1060.org/index.html to the response.
[There is a helper accessor xpur which can extract a URI from an
xpath location in an abitrary document into a canonical URI document.]
literals
If an operand, operator or param has a single nested element this is considered to be
the root of an anonymous literal document to be used by the instruction. Literals are very
useful as a quick way to specify static parameters to instructions. Literals are
read only and cannot be shared between instructions. It is a syntax error if a literal document
contains more than one root element.
The dpml instruction is used to execute a sub-routine in another DPML
document. See dpml instruction reference.
xpatheval
The xpatheval instruction is used to evaluate an xpath expression on a document
that is then cast to a boolean true/false value. Useful as a basis of conditional
processing. See xpatheval instruction reference.
Comments
Traditional XML comments using <!-- can be used, however we recommend using <comment>
elements to wrap comments. These can be placed at most places within an idoc and they will be ignored.
The benefit is that comments can be processed like regular xml and unlike XML comments they
can be nested.
<idoc> <comment>This idoc demostrates use of comments</comment> <seq> <comment>This is the <b>first</b> sequence </comment> <instr> <comment>This is an <ahref="http://www.w3.org/">XSLT</a> instruction </comment> <type>xslt</type> <operandtype="uri">file:/myOperand.xml</operand> <operatortype="uri">file:/myStylesheet.xsl</operator> <targettype="response" /> </instr> </seq> </idoc>
<comment> may contain nested XML all of which is ignored by a DPML process; comments can therefore
include XHTML which makes DPML idoc's easy to document.
Conditional Processing
DPML contains two conditional statements, a simple if-then-else
and a more complex choose statement.
The instructions within the <cond> block are executed first.
Associated with each <cond> block is a this:cond document.
The instructions within a <cond> block must at some point before the end of the block assign a canonical boolean
document to this:cond. The canonical boolean document held in this:cond is evaluated as the result of the cond
block and the conditional branch performed.
If true the <then> block is executed othewise the <else> block
is executed.
The <cond> blocks are executed in document order until one evaluates to
true. When a true condition is found the following <then> block is executed. If no conditions
are true and there is an <else> block this is executed.
Loop Processing
The structure of the looping while instruction is:
The <cond> block is executed first. This
must contain one instruction that returns a canonical boolean document.
This should be target to a variable.
If true the <seq> block is executed. The condition is the re-evaluated
and when true the <seq> block is executed again ad-infinitum.
Care should be taken to avoid infinite loops!
Exception Processing
When processing instructions things may go wrong. They may fail for one of
three categories of problem:
The idoc may contain semantic or syntactic errors. This is usually
a development-time exception.
The operand, operator, parameter or target may not be available. This is usually
a runtime exception.
The instruction may fail when executing. This is usually a runtime exception.
The first category of problem causes the idoc to terminate without any chance of catching
the exception within the current idoc. The reason being that the current idocs validity is
questionable. It is however possible, if this idoc is being executed as a sub-routine for
the invoker to detect and handle this exception.
The second and third categories of error are runtime exceptions and an idoc may wish
to handle them and act accordingly.
Exception handling blocks can be placed into the idoc at any location where an instruction
would be valid. The <exception> element may contain instructions, sub-sequences and
extended exception handling just like a regular <seq> element. It is the first exception
handler with the same parent element as the instruction that generated the exception that
will catch an exception. If none exists then the parents parent is used all the way to the root
of the idoc at which point the exception is considered unhandled.
Unhandled errors cause the termination of an idoc and the invoker will receive back a
canonical exception document which details the problem.
Inside an exception handling block the idoc has access to the exception that was thrown by using the
URI of this:exception as an operator, operand or parameter.
Exceptions can be deliberately thrown or more correctly error conditions can be
detected and programmatically converted to exceptions using the
throw instruction.
The following idoc shows an example of throwing a deliberate exception, catching it, and using
the exception:
<idoc> <seq> <instr> <type>throw</type> <operand> <ex> <id>Deliberate</id> <message>this exception was created by the throw instruction</message> </ex> </operand> </instr> <exception> <instr> <type>xslt</type> <operator>/xbin/test/xunit/data/exceptionformat.xsl</operator> <operand>this:exception</operand> <target>this:response</target> </instr> </exception> </seq> </idoc>
Canonical Document Reference
A Number of document types have been described in the DPML Guide. These
canonical document types are defined here.
URI
A canonical URI document is used to represent a single URI reference. It is used
in the curi data type. It contains a root element of <uri> and a text
value of a syntactically correct URI.
<uri>http://www.1060.org/index.html</uri>
XPath
A canonical XPath document is used to represent a single XPath statement. It is used
in the xpatheval instruction. It contains a root element of <xpath> and a
text value of a syntactically correct XPath.
<xpath>/a/b/*</xpath>
Boolean
A canonical Boolean document is used to represent a boolean state of true or false. It
is expected as the target in a conditional instruction for both if and while
statements. It contains a root element of <b> with a text value of t
or f.
<b>t</b>
Exception
A canonical Exception document is generated by the system when an exceptional situation
arises. It is available to instructions in an exception handling block by using the
this:exception URI on an operator, operand or parameter. It contains a
root <ex> element with a set of further <ex> elements. The first frame is
the deepest cause of the problem, and sucessive frames the knock-on effects. Inside each
exeception there are the following elements:
id a short identifier for the problem.
message a descriptive message describing the problem.
callstack if available, a java callstack pointing to the line of code
where the error occured.
The exception handling block may wish to use the xpatheval instruction to detect certain exceptions
and provide specific handling.
<ex> <id>CANCELED_EVENT</id> <message>No horses</message> <callstack>??</callstack> <ex> <id>BROKEN_LEG</id> <message>Fell going over a jump</message> <callstack>??</callstack> </ex> </ex>