Copyright
©
2011
2012
W3C
®
(
MIT
,
ERCIM
,
Keio
),
All
Rights
Reserved.
W3C
liability
,
trademark
and
document
use
rules
apply.
This document describes SCXML, or the "State Chart extensible Markup Language". SCXML provides a generic state-machine based execution environment based on CCXML and Harel State Tables.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This
document
is
the
ninth
tenth
Public
Working
Draft
of
SCXML
published
on
26
April
2010
16
February
2012
for
review
by
W3C
Members
and
other
interested
parties,
and
has
been
developed
by
the
Voice
Browser
Working
Group
as
part
of
the
W3C
Voice
Browser
Activity
.
The
main
difference
from
the
previous
draft
is
corrections
to
the
interpretation
algorithm.
A
diff-marked
version
of
this
document
is
also
available
for
comparison
purposes.
Comments for this specification are welcomed to www-voice@w3.org ( archives ).
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
1
Terminology
2
Overview
3
Core
Constructs
3.1
Introduction
3.2
<scxml>
3.3
<state>
3.4
<parallel>
3.5
<transition>
3.6
<initial>
3.7
<final>
3.8
<onentry>
3.9
<onexit>
3.10
<history>
3.11
Legal
State
Configurations
and
Specifications
3.12
SCXML
Events
3.13
Selecting
and
Executing
Transitions
3.14
IDs
4
Executable
Content
4.1
Introduction
4.2
<raise>
4.3
<if>
4.4
<elseif>
4.5
<else>
4.6
<foreach>
4.7
<log>
4.8
Other
Executable
Content
4.9
Evaluation
of
Executable
Content
4.10
Extensibility
of
Executable
Content
5
Data
Model
and
Data
Manipulation
5.1
Introduction
5.2
<datamodel>
5.3
<data>
5.4
<assign>
5.5
<validate>
5.6
<donedata>
5.7
<content>
5.8
<param>
5.9
<script>
5.10
Expressions
5.11
System
Variables
6
External
Communications
6.1
Introduction
6.2
<send>
6.3
<cancel>
6.4
<invoke>
6.5
<finalize>
A
Algorithm
for
SCXML
Interpretation
B
Schema
C
Conformance
C.1
Conforming
Documents
C.2
Conforming
Processors
D
Data
Models
D.1
The
Null
Data
Model
D.2
The
ECMAScript
Data
Model
D.3
The
XPath
Data
Model
E
Event
I/O
Processors
E.1
SCXML
Event
I/O
Processor
E.2
Basic
HTTP
Event
I/O
Processor
E.3
DOM
Event
I/O
Processor
F
Related
Work
G
Examples
G.1
Language
Overview
G.2
Microwave
Example
G.3
Microwave
Example
(Using
parallel)
G.4
Calculator
Example
G.5
Shale
Example
G.6
Examples
of
Invoke
and
finalize
G.7
Inline
Content
and
Namespaces
G.8
Custom
Action
Elements
H
MIME
Type
I
References
The key words MUST , MUST NOT , REQUIRED , SHALL , SHALL NOT , SHOULD , SHOULD NOT , RECOMMENDED , MAY , and OPTIONAL in this specification are to be interpreted as described in [IETF RFC 2119] .
The terms base URI and relative URI are used in this specification as they are defined in [IETF RFC 2396] .
All sections not marked as "informative" are normative.
[This section is informative.]
This document outlines State Chart XML (SCXML), which is a general-purpose event-based state machine language that combines concepts from CCXML and Harel State Tables. CCXML [W3C CCXML 1.0] is an event-based state machine language designed to support call control features in Voice Applications (specifically including VoiceXML but not limited to it). The CCXML 1.0 specification defines both a state machine and event handing syntax and a standardized set of call control elements. Harel State Tables are a state machine notation that was developed by the mathematician David Harel [Harel and Politi] and is included in UML [UML 2.3] . They offer a clean and well-thought out semantics for sophisticated constructs such as a parallel states. They have been defined as a graphical specification language, however, and hence do not have an XML representation. The goal of this document is to combine Harel semantics with an XML syntax that is a logical extension of CCXML's state and event notation.
3 Core Constructs presents the core state machine concepts, while 4 Executable Content contains an extensible set of actions that the state machine can take in response to events. 5 Data Model and Data Manipulation defines constructs for storing and modifying data, while 6 External Communications provides the capability of communicating with external entities.
[This section is informative.]
The most basic state machine concepts are 3.3 <state> , 3.5 <transition> and event ( 3.12 SCXML Events ). Each state contains a set of transitions that define how it reacts to events. Events can be generated by the state machine itself or by external entities. In a traditional state machine, the machine is always in a single state. This state is called the active state. When an event occurs, the state machine checks the transitions that are defined in the active state. If it finds one that matches the event, it moves from the active state to the state specified by the transition (called the "target" of the transition.) Thus the target state becomes the new active state.
The Harel state notation defines several extensions to these basic notions. First of all, the state machine may take actions (as defined in 4 Executable Content ) while taking transitions. Specifically, each state may contain 3.8 <onentry> and 3.9 <onexit> actions. Transitions may also contain actions. If a state machine takes transition T from state S1 to state S2, it first performs the onexit actions in S1, then the actions in T, then the onentry actions in S2. Secondly, in addition to the 'event' attribute that specifies the event(s) that can trigger it, transitions also have a 'cond' attribute. If a transition has both 'event' and 'cond' attributes, it will be selected only if an event is raised whose name matches the 'event' attribute (see 3.12.1 Event Descriptors for details) and the 'cond' condition evaluates to true. If the 'event' attribute is missing, the transition is taken whenever the 'cond' evaluates to true. If more than one transition matches, the first one in document order will be taken. Thus, in the following example, the system will transition to s1 when event e (or e.foo, etc.) occurs if x is equal to 1, but will transition to s2 if event e (or e.foo, etc.) occurs and x is not equal to 1, and will go to s3 if any other event occurs.
<state id=s"> <transition event="e" cond="x==1" target="s1"/> <transition event="e" target="s2"/> <transition event="*" target="s3"/> </state>
The data model can be changed only by the execution of <invoke> or executable content. Therefore transitions with missing 'event' attributes need be checked only after a transition has been taken. See A Algorithm for SCXML Interpretation for details.
One of the most powerful concepts in Harel notation is the idea that states may have internal structure. In particular, a <state> element may contain nested <state> elements. Such a state is called a compound state and we speak of it as the parent state, while the nested elements are child states. The child states may themselves have nested children and the nesting may proceed to any depth. Ultimately we will reach a state that does not contain any child states. Such a state is called an atomic state. When a compound state is active, one and only one of its child states is active. Conversely, when an child state is active, its parent state must be active too. Thus at any point we have a set of active states, containing an atomic state and all of its ancestors. (We will see in the next section that multiple atomic states can be active at the same time.)
In the presence of compound states, transitions no longer simply move from the current active state to a new active state, but from one set of active states to another. (See 3.11 Legal State Configurations and Specifications for details.) If the target of a transition is an atomic state, the state machine will enter not only the atomic state, but also any of its ancestor states that are not already active. Conversely, a transition may take a compound state as its target. In this case, one of the compound state's children must also become active, but the transition does not specify which one. In this case we look at the target state's 3.6 <initial> child which specifies the state's default initial state, that is, the child state to enter if the transition does not specify one. (If the default initial state is itself compound, the state machine will also enter its default initial state, and so on recursively until it reaches an atomic state.) The presence of default initial states provides a form of encapsulation, since a transition may select a compound state as its target without understanding its internal substate structure.
The default initial state of a compound state may also be specified via the 'initial' attribute. The only difference between the <initial> element and the 'initial' attribute is that the <initial> element contains a <transition> element which may in turn contain executable content which will be executed before the default state is entered. If the 'initial' attribute is specified instead, the specified state will be entered, but no executable content will be executed. (If neither the <initial> child or the 'initial' element is specified, the default initial state is the first child state in document order.) As an example, suppose that parent state S contains child states S1 and S2 in that order. If S specifies S1 as its default initial state via the 'initial' attribute (or fails to specify any initial state), then any transition that specifies S as its target will result in the state machine entering S1 as well as S. In this case, the result is exactly the same as if the transition had taken S1 as its target. If, on the other hand, S specifies S1 as its default initial state via an <initial> element containing a <transition> with S1 as its target, the <transition> can contain executable content which will execute before the default entry into S1. In this case, there is a difference between a transition that takes S as its target and one that takes S1 as its target. In the former case, but not in the latter, the executable content inside the <initial> transition will be executed.
A
compound
state
may
also
have
final
and
history
states
as
children.
3.7
<final>
is
used
to
signify
that
the
parent
state
is
in
some
sense
"done"
with
its
processing.
When
a
state
machine
enters
a
<final>
substate
of
a
compound
state,
the
parent
state
remains
active,
but
the
event
"done.state.
id
"
is
generated,
where
id
is
the
state
id
of
the
parent
state.
This
event
can
trigger
a
transition
in
any
ancestor
state
(including
the
parent).
If
the
transition
takes
a
target
outside
the
parent
state,
the
"done.state.
id
"
event
in
effect
serves
as
a
signal
that
it
is
time
to
leave
the
parent
state.
3.10
<history>
allows
for
pause
and
resume
semantics
in
compound
states.
Before
the
state
machine
exits
a
compound
state,
it
records
the
state's
active
descendents.
descendants.
If
the
'type'
attribute
of
the
<history>
state
is
set
to
"deep",
the
state
machine
saves
the
state's
full
active
descendent
descendant
configuration,
down
to
the
atomic
descendant(s).
If
'type'
is
set
to
"shallow",
the
state
machine
remembers
only
which
immediate
child
was
active.
After
that,
if
a
transition
takes
a
<history>
child
of
the
state
as
its
target,
the
state
machine
re-enters
not
only
the
parent
compound
state
but
also
the
state(s)
in
the
saved
configuration.
Thus
a
transition
with
a
deep
history
state
as
its
target
returns
to
exactly
where
the
state
was
when
it
was
last
exited,
while
a
transition
with
a
shallow
history
state
as
a
target
re-enters
the
previously
active
child
state,
but
will
enter
the
child's
default
initial
state
(if
the
child
is
itself
compound.)
Compound states also affect how transitions are selected. When looking for transitions, the state machine first looks in the most deeply nested active state(s), i.e., in the atomic state(s) that have no substates. If no transitions match in the atomic state, the state machine will look in its parent state, then in the parent's parent, etc. Thus transitions in ancestor states serve as defaults that will be taken if no transition matches in a descendant state. If no transition matches in any state, the event is discarded.
In
the
case
of
a
transition
located
in
a
compound
state,
the
'type'
attribute
is
significant.
The
behavior
of
a
transition
with
'type'
of
"external"
(the
default)
is
defined
in
terms
of
the
transition's
source
state
(which
is
the
state
that
contains
the
transition),
the
transition's
target
state(or
states),
and
the
Least
Common
Compound
Ancestor
(LCA)
(LCCA)
of
the
source
and
target
states
(which
is
the
closest
compound
state
that
is
an
ancestor
of
all
the
source
and
target
states).
When
a
transition
is
taken,
the
state
machine
will
exit
all
active
states
that
are
proper
descendants
of
the
LCA,
LCCA,
starting
with
the
innermost
one(s)
and
working
up
to
the
immediate
descendant(s)
of
the
LCA.
LCCA.
Then
the
state
machine
enters
the
target
state(s),
plus
any
states
that
are
between
it
and
the
LCA,
LCCA,
starting
with
the
outermost
one
(i.e.,
the
immediate
descendant
of
the
LCA)
LCCA)
and
working
down
to
the
target
state(s).
As
states
are
exited,
their
<onexit>
handlers
are
executed.
Then
the
executable
content
in
the
transition
is
executed,
followed
by
the
<onentry>
handlers
of
the
states
that
are
entered.
If
the
target
state(s)
of
the
transition
is
not
atomic,
the
state
machine
will
enter
their
default
initial
states
recursively
until
it
reaches
an
atomic
state(s).
In
the
example
below,
assume
that
state
s11
is
active
when
event
'e'
occurs.
The
source
of
the
transition
is
state
s1,
its
target
is
state
s21,
and
the
LCA
LCCA
is
state
S.
When
the
transition
is
taken,
first
state
S11
is
exited,
then
state
s1,
then
state
s2
is
entered,
then
state
s21.
Note
that
the
LCA
LCCA
S
is
neither
entered
nor
exited.
For
more
details
see
3.13
Selecting
and
Executing
Transitions
and
A
Algorithm
for
SCXML
Interpretation
.
<state id="S" initial="s1"> <state id="s1" initial="s11"> <onexit> <log expr="'leaving s1'"/> </onexit> <state id="s11"> <onexit> <log expr="'leaving s11'"/> </onexit> </state> <transition event="e" target="s21"> <log expr="'executing transition'"/> </transition> </state> <state id="s2" initial="s21"> <state id="s21"> <onentry> <log expr="'entering s21'"/> </onentry> </state> <onentry> <log expr="'entering s2'"/> </onentry> </state> <onentry> <log expr="'entering S'"/> <onentry> <onexit> <log expr="'leaving S'"/> <onexit> </state> ==== log output will be ======> leaving s11 leaving s1 executing transition entering s2 entering s21
The behavior of transitions with 'type' of "internal" is identical, except in the case of a transition whose source state is a compound state and whose target(s) is a descendant of the source. In such a case, an internal transition will not exit and re-enter its source state, while an external one will, as shown in the example below.
<state id="S" initial="s1"> <state id="s1" initial="s11"> <onentry> <log expr="entering S1"/> </onentry> <onexit> <log expr="'leaving s1'"/> </onexit> <state id="s11"> <onentry> <log expr="entering s11"/> </onentry> <onexit> <log expr="'leaving s11'"/> </onexit> </state> <transition event="e" target="s11" type="internal"> <log expr="'executing transition'"/> </transition> </state> ==== log output will be ======> leaving s11 executing transition entering s11 === if transition were external, log output would be ====> leaving s11 leaving s1 executing transition entering s1 entering s11
If the 'target' on a <transition> is omitted, then the value of 'type' does not have any effect and taking the transition does not change the state configuration but does invoke the executable content that is included in the transition. Note that this is different from a <transition> whose 'target' is its source state. In the latter case, the state is exited and reentered, triggering execution of its <onentry> and <onexit> executable content.
The <parallel> element represents a state whose children execute in parallel. Like <state>, the <parallel> element contains <onentry>, <onexit>, <transition>, and <state> or <parallel> children. However, the semantics of <parallel> are different. When a <state> is active, exactly one of its children is active. When a <parallel> element is active, all of its children are active. Specifically, when the state machine enters the parent <parallel> state, it also enters each child state. The child states execute in parallel in the sense that any event that is processed is processed in each child state independently, and each child state may take a different transition in response to the event. (Similarly, one child state may take a transition in reponse to an event, while another child ignores it.) When all of the children reach final states, the <parallel> element itself is considered to be in a final state, and a completion event done.state. id is generated, where id is the id of the <parallel> element.
Transitions within the individual child elements operate normally. However whenever a transition is taken with a target outside the <parallel> element, the <parallel> element and all of its child elements are exited and the corresponding <onexit> handlers are executed. The handlers for the child elements execute first, in document order, followed by those of the parent <parallel> element, followed by an action expression in the <transition> element, and then the <onentry> handlers in the "target" state.
In the following example, parallel state 'p' has two children S1 and S2. Suppose a transition takes S1's child S12 as a target. (Note that this is permitted even though S12 is not the default initial state for S1 and that S11 is not, in fact, visited in the course of this example). Upon this transition, the state machine, in addition to enterering S1 and S12, will also enter S1's parallel sibling S2 and its initial state S21. Once the transition has been taken, p, S1, S2, S12, and S21 will all be active. If event 'e1' occurs, it will cause S12 to transition to S1Final, and S21 to transition to S22. Entering S1Final will cause the event done.state.S1 to be generated. At this point, S1 is in a final state, but S2 is still active. Now suppose event 'e2' occurs. This will cause S22 to transition to S2Final, and the event done.state.S2 will be generated. Furthermore, since all of p's children are now in final states, the event 'done.state.p' will be generated, which will cause the transition contained in p to be triggered, exiting the entire region.
<parallel id="p"> <transition event="done.state.p" target="someOtherState"/> <state id="S1" initial="S11"> <state id="S11"> <transition event="e4" target="S12"/> </state> <state id="S12"> <transition event="e1" target="S1Final"/> </state> <final id="S1Final"/> </state> <state id="S2" initial="S21"> <state id=S21"> <transition event="e1" target="S22"/> </state> <state id="S22"> <transition event="e2" target="S2Final/> </state> <final id="S2Final"/> </state> </parallel>
Note that the semantics of the <parallel> does not call for multiple threads or truly concurrent processing. The children of <parallel> execute in parallel in the sense that they are all simultaneously active and each one independently selects transitions for any event that is received. However, the parallel children process the event in a defined, serial order, so no conflicts or race conditions can occur. See A Algorithm for SCXML Interpretation for a detailed description of the semantics <parallel> and the rest of SCXML.
[This section is normative.]
The top-level wrapper element, which carries version information. The actual state machine consists of its children. Note that only one of the children is active at any one time. See 3.11 Legal State Configurations and Specifications for details.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
initial | false | none | IDREFS | none | A legal state specification. See 3.11 Legal State Configurations and Specifications for details. | The id of the initial state(s) for the document. If not specified, the default initial state is the first child state in document order. |
name | false | none | NMTOKEN | none | Any valid NMTOKEN | The name of this state machine. It is for purely informational purposes. |
xmlns | true | none | URI | none |
The
value
|
|
version | true | none | decimal | none |
The
|
|
datamodel | false | none | NMTOKEN |
|
|
The
datamodel
that
this
document
requires.
|
binding | false | enum | "early" | "early", "late" | The data binding to use. See 5.3.3 Data Binding and Scoping for details. | |
exmode | false | enum | "lax" | "lax", "strict" | Determines whether the processor should silently ignore markup that it does not support. |
If 'exmode' is "lax", the SCXML processor MUST silently ignore any markup that it does not support, including markup in non-scxml namespaces. (Examples of unsupported elements include elements that are not part of the specified data model or executable content that some other platform has defined as an extension.) If 'exmode' is "strict", the SCXML processor MUST treat such markup as syntactically invalid and reject the document at initialization time. Platforms SHOULD document their default datamodel.
[This section is normative.]
Holds the representation of a state.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | false | none | ID | none | A valid id as defined in [XML Schema] | The identifier for this state. See 3.14 IDs for details. |
initial | false |
|
IDREFS | none | A legal state specification. See 3.11 Legal State Configurations and Specifications for details. | The id of the default initial state (or states) for this state. |
[
Definition
:
An
atomic
state
is
one
that
has
no
<state>
or
<state>,
<parallel>
or
<final>
children.]
[ Definition : A compound state is one that has <state>, <parallel>, or <final> children (or a combination of these).]
In
a
conformant
SCXML
document,
a
compound
state
MAY
specify
either
an
"initial"
attribute
or
an
<initial>
element,
but
not
both.
See
3.6
<initial>
for
a
discussion
of
the
difference
between
the
two
notations.
If
neither
the
"initial"
attribute
nor
an
<initial>
element
is
specified,
the
default
initial
state
is
SCXML
Processor
MUST
use
the
first
child
state
in
document
order.
order
as
the
default
initial
state.
[This section is normative.]
The <parallel> element encapsulates a set of child states which are simultaneously active when the parent element is active.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | false | ID | none | A valid id as defined in [XML Schema] | The identifier for this state. See 3.14 IDs for details. |
[This section is normative.]
Transitions between states are triggered by events and conditionalized via guard conditions. They may contain executable content, which is executed when the transition is taken.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
event | false |
|
EventsTypes.datatype. | none | A space-separated list of event descriptors. See 3.12.1 Event Descriptors for details. |
A
list
of
designators
of
events
that
trigger
this
transition.
|
cond | false | Boolean expression | 'true' | Any boolean expression. See 5.10.1 Conditional Expressions for details. |
The
guard
condition
for
this
transition.
|
|
target | false | . | IDREFS | none | A legal state specification. See 3.11 Legal State Configurations and Specifications for details. | The identifier(s) of the state or parallel region to transition to. See 3.13 Selecting and Executing Transitions and A Algorithm for SCXML Interpretation for details. |
type | false | enum | "external" | "internal" "external" | Determines whether the source state is exited in transitions whose target state is a descendant of the source state. See 3.13 Selecting and Executing Transitions for details. |
A conformant SCXML document MUST specify at least one of 'event', 'cond' or 'target'. 3.13 Selecting and Executing Transitions contains more detail on the semantics of transitions.
[This section is normative.]
This element represents the default initial state for a complex <state> element (i.e. one one containing child <state> or <parallel> elements.
[This section is normative.]
<final> represents a final state of an <scxml> or compound <state> element.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | false | ID | none | A valid id as defined in [XML Schema] | The identifier for this state. See 3.14 IDs for details. |
When
the
state
machine
enters
the
<final>
child
of
a
<state>
element,
the
SCXML
processor
MUST
after
generate
the
event
done.state.
id
after
completion
of
the
<onentry>
elements,
where
id
is
the
id
of
the
parent
state.
When
the
state
machine
reaches
the
<final>
child
of
an
<scxml>
element,
it
MUST
terminate.
See
A
Algorithm
for
SCXML
Interpretation
for
details.
If
the
SCXML
session
was
triggered
as
the
result
by
an
<invoke>
element
in
another
session,
the
SCXML
processor
MUST
generate
the
event
done.invoke.
id
after
termination
and
return
it
to
the
other
session,
where
id
is
the
unique
identifier
generated
when
the
<invoke>
element
was
executed.
See
6.4
<invoke>
for
details.
[This section is normative.]
A wrapper element containing executable content to be executed when the state is entered.
The children of the <onentry> handler consist of executable content as defined in 4 Executable Content .
The SCXML processor MUST execute the <onentry> handlers of a state in document order when the state is entered. In doing so, it MUST treat each handler as a separate block of executable content. See A Algorithm for SCXML Interpretation for details.
[This section is normative.]
A wrapper element containing executable content to be executed when the state is exited.
The children of the <onexit> handler consist of executable content as defined in 4 Executable Content .
The SCXML processor MUST execute the <onexit> handlers of a state in document order when the state is exited. In doing so, it MUST treat each handler as a separate block of executable content. See A Algorithm for SCXML Interpretation for details.
The <history> pseudo-state allows allows a state machine to remember its state configuration. A <transition> taking the <history> state as its target will return the state machine to this recorded configuration.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | false | ID | none | A valid id as defined in [XML Schema] | Identifier for this pseudo-state. See 3.14 IDs for details. | |
type | false | enum | "shallow" | "deep" or "shallow" | Determines whether the active atomic substate(s) of the current state or only its immediate active substate(s) are recorded. |
If
the
'type'
of
a
<history>
element
is
"shallow",
the
SCXML
processor
MUST
record
the
immediately
active
children
of
its
parent
before
taking
any
transition
that
exits
the
parent.
If
the
'type'
of
a
<history>
element
is
"deep",
the
SCXML
processor
MUST
record
the
active
atomic
descendents
descendants
of
the
parent
before
taking
any
transition
that
exits
the
parent.
Before
After
the
parent
state
has
been
visited
for
the
first
time,
we
define
the
set
of
states
that
the
SCXML
processor
MUST
treat
has
recorded
to
be
the
default
history
configuration,
which
is
'stored
state
configuration'.
We
also
define
the
states
specified
by
the
'target'
of
the
<history>
element's
<transition>
child,
as
if
it
were
child
to
be
the
'default
stored
configuration.
state
configuration.'
If
a
transition
is
executed
that
takes
the
<history>
state
as
its
target,
the
behavior
depends
on
whether
the
parent
state
has
been
visited
before.
If
it
has,
the
SCXML
processor
MUST
behave
as
if
the
transition
had
taken
the
stored
state
configuration
as
its
target.
If
it
has
not,
the
SCXML
processor
MUST
behave
as
if
the
transition
had
taken
the
default
stored
state
configuration
as
its
target.
(Note
target.(Note
that
in
a
conformant
SCXML
document,
a
<state>
or
<parallel>
element
MAY
have
both
"deep"
and
"shallow"
<history>
children.)
[This section is normative.]
[ Definition : A <state> or <parallel> element is active if it has been entered by a transition and has not subsequently been exited.]
[ Definition : The state configuration of a state machine is the set of currently active states. ]
An SCXML document places the state machine in an initial state configuration at initialization time (via the 'initial' attribute of the <scxml> element). Each transition that the state machine takes thereafter places the state machine in another state configuration (which need not be distinct from the former one.) A conformant SCXML document MUST place the state machine only in legal state configurations, where a legal state configuration is one that meets the following conditions:
It follows from this definition that if a state machine is in more than one atomic state, the atomic states can be traced back through a chain of <state> or >parallel> ancestors to a single <parallel> ancestor.
The 'target' attribute of a <transition> (or the 'initial' attribute of a <state> or <scxml> element) do not in the general case specify a full legal state configuration since 1) they can contain <parallel> or non-atomic <state> elements 2) they do not contain the ancestors of the states in the list. We therefore define a legal state specification to be a set of states such that 1) no state is an ancestor of any other state on the list, and 2) a full legal state configuration results when all ancestors and default initial descendants have been added. (Note that the process of adding default initial descendants is recursive, since the 'initial' value may itself be non-atomic.) In a conformant SCXML document, the value of an 'initial' attribute or the 'target' of a <transition> MUST either be empty or contain a legal state specification.
In a conformant SCXML document, there is an additional requirement on the value of the 'initial' attribute of a <state> and on the 'target' of a <transition> inside an <initial> element: all the states MUST be descendants of the containing <state> element.
[This section is normative.]
Events are one of the basic concepts in SCXML since they drive most transitions. The internal structure of events is platform-specific as long as the following external interface is observed:
For the most part, the set of events raised during the execution of an SCXML document is application-specific and generated under author control by use of the <raise> and <send> elements. However, certain events are mandatory and generated automatically by the interpreter. These are described in 3.12 SCXML Events . Platforms MAY extend the names of these automatically generated events by adding a suffix. For example, a platform could extend done.state. id with a timestamp suffix and generate done.state. id.timestamp instead. Because any prefix of done.state. id is also a prefix of done.state. id.timestamp , any transition that matches the former event will also match the latter.
Like an event name, an event descriptor is a series of alphanumeric characters segemented into tokens by the "." character. The 'event' attribute of a transition consists of one or more such event descriptors separated by spaces.
[ Definition : A transition matches an event if at least one of its event descriptors matches the event's name. ]
[ Definition : An event descriptor matches an event name if its string of tokens is an exact match or a prefix of the set of tokens in the event's name. In all cases, the token matching is case sensitive. ]
For example, a transition with an 'event' attribute of "error foo" will match event names "error", "error.send", "error.send.failed", etc. (or "foo", "foo.bar" etc.) but would not match events named "errors.my.custom", "errorhandler.mistake","errOr.send" or "foobar".
For compatibility with CCXML, and to make the prefix matching possibly more clear to a reader of the SCXML document, an event descriptor MAY also end with the wildcard '.*', which matches zero or more tokens at the end of the processed event's name. Note that a transition with 'event' of "error", one with "error.", and one with "error.*" are functionally equivalent since they are token prefixes of exactly the same set of event names.
An event designator consisting solely of "*" can be used as a wildcard matching any sequence of tokens, and thus any event. Note that this is different from a transition lacking the 'event' attribute altogether. Such an eventless transition does not match any event, but will be taken whenever its 'cond' attribute evaluates to 'true'. As shown in A Algorithm for SCXML Interpretation , the SCXML interpreter will check for such eventless transitions when it first enters a state, before it looks for transitions driven by internal or external events.
Once the SCXML processor has begun executing a well-formed SCXML document, it MUST signal any errors that occur by raising SCXML events whose names begin with 'error.'. the processor MUST place these events in the internal event queue and MUST process them like any other event. (Note in particular, they are not processed immediately if there are other events in the queue and they are ignored if no transition is found that matches them.) Two error events are defined in this specification: 'error.communication' and 'error.execution'. The former cover errors occurring while trying to communicate with external entities, such as those arising from <send> and <invoke>, while the latter category consists of errors internal to the execution of the document, such as those arising from expression evaluation.
The set of error events may be extended in future versions of this specification. However, the set of names beginning with 'error.platform' is reserved for platform- and application-specific errors. Therefore applications and platforms MAY extend the set of errors defined in this specification in two ways. First by adding a suffix to an error name defined in this specification, and second by using 'error.platform' with or without a suffix. In addition, platforms MAY include additional information about the nature of the error in the 'data' field of the event. See 5.11 System Variables for details.
Note however that authors can arrange for otherwise unhandled errors to cause the interpreter to exit by creating a transition with "event" attribute of 'error' and a target of any top-level final state (i.e. one that is a child of <scxml>). If such a transition T is placed in a state S, it will cause the state machine to terminate on any error that is raised in S or one of its substates and is not handled by another transition that is placed in a substate of S or in S and preceding T in document order.
The following events are generated automatically by the SCXML implementation under conditions defined elsewhere in this document.
Name | Description | Defined in | See also |
---|---|---|---|
done.state. id | Indicates that the state machine has entered a final substate of state id . | 3.7 <final> | 3.1 Introduction |
done.invoke. id | Indicates that the invoked process with invokeid id has completed processing. | 6.4 <invoke> | 3.7 <final> , exitInterpreter procedure in A Algorithm for SCXML Interpretation |
cancel.invoke. id | Sent from an invoking session to an invoked session to terminate its processing. | 6.4.3 Implementation of <invoke> | E.1 SCXML Event I/O Processor |
error.communication | Indicates that an error has occurred while trying to communicate with an external entity. | 3.12.2 Errors | 6.2 <send> , E.1 SCXML Event I/O Processor , E.2 Basic HTTP Event I/O Processor , E.3 DOM Event I/O Processor |
error.execution | Indicates that an error internal to the execution of the document has occurred, such as one arising from expression evaluation. | 3.12.2 Errors | 4.6 <foreach> , 5.4 <assign> , 5.8 <param> , 5.10.1 Conditional Expressions , 5.10.2 Location Expressions , 5.10.3 Legal Data Values and Value Expressions , 5.10.4 Errors in Expressions , 5.11 System Variables , 6.2 <send> , D.2.3 Location Expressions , D.2.5 <assign> , D.3.5 <assign> |
error.platform | Indicates that a platform- or application-specific error has occurred. | 3.12.2 Errors |
[This section is normative.]
To simplify the following definitions, we introduce the event NULL. NULL has no name and is used only in these definitions. It nevers occurs in the event queues of an SCXML Processor. All other events have names and are distinct from NULL. (In effect, NULL is a pseudo-event that is used in these definitions as a trigger for eventless transitions.)
[ Definition : A transition T is enabled by named event E in atomic state S if a) T's source state is S or an ancestor of S, b) T matches E's name (see 3.12.1 Event Descriptors ) c) T lacks a 'cond' attribute or its 'cond' attribute evaluates to "true". A transition is enabled by NULL in atomic state S if a) T lacks an 'event' attribute b) T's source state is S or an ancestor of S c) T lacks an 'cond' attribute or its 'cond' attribute evaluates to "true". (Note that such a transition can never be enabled by any named event.)]
[
Definition
:
A
transition
T
is
optimally
enabled
by
event
E
in
atomic
state
S
if
a)
T
is
enabled
by
E
in
S
and
b)
no
transition
that
precedes
T
in
document
order
in
T's
source
state
is
enabled
by
E
in
S
and
c)
no
transition
is
enabled
by
E
in
S
in
any
descendent
descendant
of
T's
source
state.]
[ Definition : The optimal transition set enabled by event E in state configuration C is the largest set of transitions such that each transition in the set is optimally enabled by E in an atomic state in C and no transition has a source state that is exited by another transition in the set that proceeds it in document order. ]
[ Definition : The source state of a transition is the <state> or <parallel> element that it occurs in. The target state(s) of the transition is the state or set of states specified by its 'target' attribute. The complete target set of a transition consists of all the states that will be active after the transition is taken. It contains the target states of the transition plus all their ancestors, expanded by the recursive application of the following two operations: 1) if any <parallel> element is a member of the set, any of its children that are not members of the set must be added 2) if any compound <state> is in the set and none of its children is in the set, its default initial state is added to the set. Any state whose child(ren) are added to the complete target set by clause 2 is called a default entry state . ]
[
Definition
:
The
exit
set
of
a
transition
is
the
set
of
states
that
are
exited
when
the
transition
is
taken.
If
the
transition
does
not
contain
a
'target',
its
exit
set
is
empty.
Otherwise
(i.e.,
if
the
transition
contains
a
'target'),
if
it
its
'type'
of
is
"external",
its
exit
set
consists
of
all
active
states
that
are
proper
descendents
descendants
of
the
Least
Common
Compound
Ancestor
(LCA)
(LCCA)
of
the
source
and
target
states.
Otherwise,
if
the
transition
has
'type'
"internal"
"internal",
its
source
state
is
a
compound
state,
and
all
its
target
states
are
proper
descendents
descendants
of
its
source
state,
the
target
exit
set
consists
of
all
active
states
that
are
proper
descendents
descendants
of
its
source
state.
(If
a
transition
has
'type'
of
"internal",
but
but
its
source
state
is
not
compound
or
its
target
states
are
not
all
proper
descendents
descendants
of
its
source
state,
its
exit
set
is
defined
as
if
it
had
'type'
of
"external".
The
exit
set
of
a
set
of
transitions
is
the
union
of
the
exit
sets
of
the
individual
transitions.
]
[ Definition : The entry set of a transition is the set of states that are entered when the transition is taken. If a transition does not contain a 'target', its entry set is empty. Otherwise, it consists of all members of the transitions complete target set that are not currently active. The entry set of a set of transitions is the union of the transition sets of the individual transitions.]
[ Definition : A microstep consists of the execution of the transitions in an optimal enabled transition set.]
[ Definition : A macrostep is a series of one or more microsteps ending in a configuration where the internal event queue is empty and no transitions are enabled by NULL. ]
To execute a microstep, the SCXML Processor MUST execute the transitions in the corresponding optimal enabled transition set. To execute a set of transitions, the SCXML Processor MUST first exit all the states in the transitions' exit set in exit order . It MUST then execute the executable content contained in the transitions in document order. It MUST then enter the states in the transitions' entry set in entry order .
To exit a state, the SCXML Processor MUST execute the executable content in the state's <onexit> handler. Then it MUST cancel any ongoing invocations that were triggered by that state. Finally, the Processor MUST remove the state from the active state's list.
To enter a state, the SCXML Processor MUST add the state to the active state's list. Then it MUST execute the executable content in the state's <onentry> handler. If the state is a default entry state and has an <initial> child, the SCXML Processor MUST then execute the executable content in the <initial> child's <transition>.
At startup, the SCXML Processor MUST place the state machine in the configuration specified by the 'initial' attribute of the <scxml> element.
After entering the initial configuration, and after executing each microstep, the SCXML Processor MUST check the state configuration for <final> states that it has entered during the microstep. If it has entered a <final> state that is a child of <scxml>, it MUST halt processing. If it has entered a <final> state that is a child of a compound state, it MUST generate the event done.state. id , where id is the id of the compound state. If the compound state is itself the child of a <parallel> element, and all the <parallel> element's other children are in final states, the Processor MUST generate the event done.state. id , where id is the id of the <parallel> elements.
After checking the state configuration, the Processor MUST select the optimal transition set enabled by NULL in the current configuration. If the set is not empty, it MUST execute it as a microstep. If the set is empty, the Processor MUST remove events from the internal event queue until the queue is empty or it finds an event that enables a non-empty optimal transition set in the current configuration. If it finds such a set, the processor MUST then execute it as a microstep. (Otherwise the internal event queue is empty and the Processor has completed a macrostep.)
After completing a macrostep, the SCXML Processor MUST execute in document order the <invoke> handlers in all states that have been entered since the completion of the last macrostep. Then the Processor MUST remove events from the external event queue, waiting till events appear if necessary, until it finds one that enables a non-empty optimal transition set in the current configuration. The Processor MUST then execute that set as a microstep.
See A Algorithm for SCXML Interpretation for more details.
[This section is normative.]
In
a
conformant
SCXML
document,
the
values
of
all
attributes
of
type
"id"
MUST
be
unique
within
the
session.
When
such
an
attribute
is
defined
to
be
optional
and
the
author
omits
it,
then,
for
elements
other
than
<send>
and
<invoke>,
the
SCXML
processor
MUST
generate
a
unique
one
id
automatically
at
document
load
time.
(Note
that
Such
system
generated
IDs
cannot
normally
be
referenced
elsewhere
in
the
document
because
they
are
not
known
to
the
author.
In
particular,
a
state
with
a
system
generated
ID
cannot
be
the
target
of
a
transition.)
The
ids
for
<send>
and
<invoke>
are
subtly
different.
In
a
conformant
SCXML
document,
they
MUST
be
unique
within
the
session,
but
in
the
case
where
the
author
does
not
provide
them,
the
processor
MUST
generate
a
new
unique
ID
not
at
load
time
but
each
time
the
element
is
executed
.
Furthermore
the
attribute
'idlocation'
can
be
used
to
capture
this
automatically
generated
id.
Finally
note
that
the
automatically
generated
id
for
<invoke>
has
a
special
format.
See
6.4.1
Attribute
Details
for
details.
The
SCXML
processor
MAY
generate
all
other
ids
in
any
format,
as
long
as
they
are
unique.
[This section is informative.]
Executable content allows the state machine to do things. It provides the hooks that allow an SCXML session to modify its data model and interact with external entities. Executable content consists of actions that are performed as part of taking transitions. In particular, executable content occurs inside <onentry> and <onexit> elements as well as inside transitions. When the state machine takes a transition, it executes the <onexit> executable content in the states it is leaving, followed by the content in the transition, followed by the <onentry> content in the states it is entering. See A Algorithm for SCXML Interpretation for details.
This standard defines elements of executable content which can raise events 4.2 <raise> , communicate with external entities 6.2 <send> , log information 4.7 <log> execute scripts 5.9 <script> and modify the data model 5.4 <assign> , as well as control constructs to conditionalize execution 4.3 <if> and to iterate over the items in a collection 4.6 <foreach> . In addition, SCXML implementations are allowed to define their own, platform-specific executable content (see 4.10 Extensibility of Executable Content ).
[This section is normative.]
The <raise> element raises an event in the current SCXML session. Note that the event will not be processed until the current block of executable content has completed and all events that are already in the internal event queue have been processed. For example, suppose the <raise> element occurs first in the <onentry> handler of state S followed by executable content elements ec1 and ec2. If event e1 is already in the internal event queue when S is entered, the event generated by <raise> will not be processed until ec1 and ec2 have finished execution and e1 has been processed. For details of event processing, see A Algorithm for SCXML Interpretation . Note that the 6.2 <send> element may also be used to raise internal events in an SCXML session. The <send> is a general-purpose message element, while <raise> has a simpler syntax.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
event | true | NMTOKEN | none | Specifies the name of the event. This will be matched against the 'event' attribute of transitions. |
The SCXML processor MUST place the event that is generated at the rear of the session's internal event queue.
[This section is normative.]
<if> is a container for conditionally executed elements.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
cond | true | Conditional expression | none | A valid conditional expression | A boolean expression. See 5.10.1 Conditional Expressions for details. |
The behavior of <if> is defined in terms of partitions of executable content. The first partition consists of the executable content between the <if> and the first <elseif>, <else> or </if> tag. Each <elseif> tag defines a partition that extends from it to the next <elseif>, <else> or </if> tag. The <else> tag defines a partition that extends from it to the closing </if> tag. In a conformant SCXML document, a partition MAY be empty. In a conformant SCXML document, <else> MUST occur after all <elseif> tags.
When the <if> element is executed, the SCXML processor MUST execute the first partition in document order that is defined by a tag whose 'cond' attribute evaluates to true, if there is one. Otherwise, it MUST execute the partition defined by the <else> tag, if there is one. Otherwise it MUST NOT execute any of the executable content.
Here is an example:
<if cond="cond1"> <!-- selected when "cond1" is true --> <elseif cond="cond2"/> <!-- selected when "cond1" is false and "cond2" is true --> <elseif cond="cond3"/> <!-- selected when "cond1" and "cond2" are false and "cond3" is true --> <else/> <!-- selected when "cond1", "cond2", and "cond3" are false --> </if>
[This section is normative.]
[This section is normative.]
The <foreach> element allows an SCXML application to iterate through a collection in the data model and to execute the actions contained within it for each item in the collection.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
array | true | Value expression | none | A value expression that evaluates to an iterable collection. | The <foreach> element will iterate over a shallow copy of this collection. | |
item | true | xsd:string | none | Any variable name that is valid in the specified data model. | A variable that stores a different item of the collection in each iteration of the loop. | |
index | false | xsd:string | none | Any variable name that is valid in the specified data model. | A variable that stores the current iteration index upon each iteration of the foreach loop. |
The children of <foreach> consist of one or more items of executable content. (Note that they are considered to be part of the same block of executable content as the parent <foreach> element.)
The SCXML processor MUST declare a new variable if the one specified by 'item' is not already defined. If 'index' is present, the SCXML processor MUST declare a new variable if the one specified by 'index' is not already defined. If 'array' does not evaluate to a legal iterable collection, or if 'item' does not specify a legal variable name, the SCXML processor MUST terminate execution of the <foreach> element and the block that contains it, and place the error error.execution on the internal event queue.
The
SCXML
processor
MUST
act
as
if
it
has
made
a
shallow
copy
of
the
collection
produced
by
the
evaluation
of
'array'.
Specifically,
modifications
to
the
collection
during
the
execution
of
<foreach>
MUST
NOT
affect
the
iteration
behavior.
The
SCXML
processor
MUST
start
with
the
first
item
in
the
collection
and
proceed
to
the
last
item
in
the
iteration
order
that
is
defined
for
the
collection.
(This
order
depends
on
the
data
model
in
use.
)
For
each
item,
item
in
turn,
the
processor
MUST
act
as
if
it
has
made
a
shallow
copy
or
reference
and
assign
it
to
the
item
variable.
(Note
that
the
assigned
value
MAY
be
null
or
undefined
if
the
collection
contains
a
null
or
undefined
item.)
After
making
the
assignment,
the
SCXML
processor
MUST
evaluate
its
child
executable
content.
It
MUST
then
proceed
to
the
next
item
in
iteration
order.
If
the
evaluation
of
any
child
element
causes
an
error,
the
processor
MUST
cease
execution
of
the
<foreach>
element
and
the
block
that
contains
it.
(Note
that
SCXML
does
not
provide
break
functionality
to
interrupt
<foreach>,
however
targetless
and/or
eventless
transitions
can
provide
sophisticated
iterative
behavior
within
the
SCXML
application
itself.)
[This section is normative.]
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
label | false | string | empty string | A character string with an implementation-dependent interpretation. It is intended to provide meta-data about the log string specified by 'expr'. | ||
expr |
|
Value expression | none | An expression returning the value to be logged. See 5.10.3 Legal Data Values and Value Expressions for details. The nature of the logging mechanism is implementation-dependent. For example, the SCXML processor may convert this value to a convenient format before logging it. |
The
manner
in
which
the
message
is
displayed
or
logged
is
platform-dependent.
The
SCXML
processor
MUST
insure
ensure
that
<log>
has
no
side-effects
on
document
interpretation.
[This section is normative.]
The following elements of executable content are defined elsewhere in this specification. They MAY occur wherever executable content is allowed and MUST NOT occur anyplace else.
[This section is normative.]
Wherever executable content is permitted, an arbitrary number of elements MAY occur. Such a sequence of elements of executable content is called a block. For example, if transition t takes the state machine from atomic state S1 to atomic state S2, there are three blocks of executable content executed: the one in the <onexit> handler of S1, the one inside t, and the one inside the <onentry> handler of S2. The SCXML processor MUST execute the elements of a block in document order. If the processing of an element causes an error to be raised, the processor MUST NOT process the remaining elements of the block. (The execution of other blocks of executable content is not affected.)
Events raised during the processing of executable content are treated like any other events. Note in particular, that error events will not be removed from the queue and processed until all events preceding them in the queue have been processed. See 3.12.2 Errors and A Algorithm for SCXML Interpretation for details.
[This section is normative.]
Implementations
MAY
may
provide
additional
executable
content
corresponding
to
special
features
of
their
implementations.
The
functionality
of
such
platform-specific
content
is
not
restricted,
except
that
it
MUST
NOT
cause
transitions
or
any
form
of
change
of
state
(except
indirectly,
by
raising
events
that
trigger
transitions).
Note
that
SCXML
treats
the
executable
content
triggered
by
a
transition
as
a
single
blocking
operation
and
that
no
events
are
processed
until
all
the
executable
content
has
completed.
For
example,
when
taking
a
transition
into
state
S,
the
SCXML
processor
will
not
process
any
events
or
take
any
transitions
until
all
<onentry>
handlers
in
S
have
finished.
It
is
thus
important
that
all
executable
content,
including
platform-specific
extensions,
execute
swiftly.
In a conformant SCXML document any extensions to executable content MUST NOT be defined the 'scxml' namespace. (Note that the schema B Schema allows elements from arbitrary namespaces inside blocks of executable content.) The following example shows the incorporation of CCXML functionality (see [W3C CCXML 1.0] ) into SCXML. In particular an <accept> element in the 'ccxml' namespace is invoked as executable content inside a transition.
<transition event="ccxml:connection.alerting"> <ccxml:accept connectionid="_event.data.connectionid"/> </transition>
This markup is legal on any SCXML interpreter, but the behavior of <accept> element is platform-dependent. See C.2 Conforming Processors for details.
A general method for implementing extensions using the <send> element is presented in G.8 Custom Action Elements .
[This section is informative.]
The
Data
Model
offers
the
capability
of
storing,
reading,
and
modifying
a
set
of
data
that
is
internal
to
the
state
machine.
This
specification
does
not
mandate
any
specific
data
model,
but
instead
defines
a
set
of
abstract
capabilities
that
can
be
realized
by
various
languages,
such
as
ECMAScript
or
XML/XPath.
Implementations
may
choose
the
set
of
data
models
that
they
support.
In
addition
to
the
underlying
data
structure,
the
data
model
defines
a
set
of
expression
expressions
as
described
in
5.10
Expressions
.
These
expressions
are
used
to
refer
to
specific
locations
in
the
data
model,
to
compute
values
to
assign
to
those
locations,
and
to
evaluate
boolean
conditions.
Finally,
the
data
model
includes
a
set
of
system
variables,
as
defined
in
5.11
System
Variables
,
which
are
automatically
maintained
by
the
SCXML
processor.
The data model is defined via the 5.2 <datamodel> element, which contains zero or more 5.3 <data> elements, each of which defines a single data element and assigns an initial value to it. These values may be specified in-line or loaded from an external source. They can then be updated via the 5.4 <assign> element. The 5.5 <validate> element can be used to validate the data (in data models where that makes sense), while the 5.6 <donedata> , 5.7 <content> , and 5.8 <param> elements can be used to incorporate data into communications with external entities. Finally, the 5.9 <script> element permits the incorporation of a scripting language.
The interpretation of these elements depends on the datamodel in question, and not all elements are supported in all datamodels. For the details of specific data models, see D Data Models .
[This section is normative.]
<datamodel> is a wrapper element which encapsulates any number of <data> elements, each of which defines a single data object. The exact nature of the data object depends on the data model language used.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
schema | false | URI | none | Location of the schema for this datamodel | URL of the schema for this datamodel. See 5.5 <validate> for its use. The exact nature of the schema depends on the data model language being used. |
In
a
conformant
SCXML
document,
the
'schema'
attribute
MAY
occur
on
the
top-level
<datamodel>
elemen,
element,
namely
the
one
that
is
a
child
of
<scxml>.
It
MUST
NOT
occur
on
any
other
<datamodel>
element.
[This section is normative.]
The <data> element is used to declare and populate portions of the datamodel.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | true | ID | none | The name of the data item. See 3.14 IDs for details. | ||
src | false | URI | none | Gives the location from which the data object should be fetched. See 5.10.3 Legal Data Values and Value Expressions for details. | ||
expr | false | Expression | none | Any valid value expression | Evaluates to provide the value of the data item. See 5.10.3 Legal Data Values and Value Expressions for details. |
The children of the <data> element represent an in-line specification of the value of the data object.
In a conformant SCXML document, a <data> element MAY have either a 'src' or an 'expr' attribute, but MUST NOT have both. Furthermore, if either attribute is present, the element MUST NOT have any children. Thus 'src', 'expr' and children are mutually exclusive in the <data> element.
The
SCXML
Processor
MUST
must
allow
use
any
values
provided
by
the
environment
to
provide
values
for
at
instantiation
time
in
place
of
those
contained
in
the
top-level
<data>
elements.
(Top-level
data
elements
(namely
are
those
that
are
children
of
the
<datamodel
>
element
that
is
a
child
of
<scxml>).
Specifically,
the
Processor
MUST
use
the
values
provided
at
instantiation
time
instead
of
those
contained
in
thee
<data>
elements.
The
manner
in
which
the
environment
specifies
these
overriding
values
is
platform-dependent.
If the value specified (by 'src', children, or the environment) is not a legal data value, the SCXML Processor MUST create an empty data element in the data model with the specified id. Note that what constitutes a legal data value depends on the data model language used. See D Data Models for details.
There
is
a
single
globally
visible
data
model
for
the
entire
state
machine.
Specifically,
the
SCXML
processor
Processor
MUST
allow
any
data
element
to
be
accessed
from
any
state.
Thus
the
data
model
has
no
concept
of
scoping.
However,
authors
control
when
the
initial
values
are
assigned
to
the
data
elements
by
means
of
the
'binding'
attribute
on
the
<scxml>
element.
When
'binding'
is
assigned
the
value
"early"
(the
default),
the
scxml
processor
SCXML
Processor
MUST
create
all
data
elements
and
assign
their
initial
values
at
document
initialization
time.
When
'binding'
is
assigned
the
value
"late",
the
scxml
processor
SCXML
Processor
MUST
create
the
data
elements
at
document
initialization
time,
but
MUST
assign
the
value
specified
by
'expr'
to
a
given
data
element
only
when
the
state
that
contains
it
is
entered
for
the
first
time,
before
any
<onentry>
markup.
(The
value
of
the
data
element
between
the
time
it
is
created
and
the
time
its
parent
state
is
first
entered
will
depend
on
the
data
language
chosen.
The
value
specified
by
'expr'
will
be
assigned
to
the
data
element
even
if
the
element
already
has
a
non-null
value
when
the
parent
state
is
first
entered.)
Ordering
dependencies
between
<data>
elements
are
not
permitted.
In
the
case
of
early
binding,
the
scxml
processor
SCXML
Processor
MUST
evaluate
all
<data>
elements
at
initialization
time
but
MAY
do
so
in
any
order
it
chooses.
Suppose,
for
example,
that
the
declaration
of
element
"a"
precedes
the
declaration
of
element
"b"
in
a
document.
It
is
not
safe
to
assume
that
"a"
will
be
instantiated
and
have
a
value
when
the
declaration
of
"b"
is
executed.
Therefore
the
"expr"
in
"b"
cannot
safely
reference
the
value
of
"a"
(and
vice-versa).
When
late
binding
is
selected,
the
scxml
processor
SCXML
Processor
MUST
create
data
model
elements
at
initialization
time
but
MAY
do
so
in
any
order
it
chooses.
Similarly,
the
processor
MUST
assign
the
value
specified
by
'expr'
to
data
elements
only
when
the
state
containing
them
is
first
entered,
but
MAY
do
so
in
any
order
it
chooses.
Values
created
by
<data>
elements
are
local
to
their
session.
In
particular,
the
scxml
processor
SCXML
Processor
MUST
insure
ensure
that
such
values
are
changed
only
by
the
execution
of
executable
content
or
the
<finalize>
element.
Note
that
in
addition
to
the
author-controlled
<data>
elements
there
are
system
variables
whose
values
are
maintained
by
the
scxml
processor.
SCXML
Processor.
See
5.11
System
Variables
for
details.
[This section is normative.]
The <assign> element is used to modify the data model.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
location | true | path expression | none | Any valid location expression. | The location in the data model into which to insert the new value. See 5.10.2 Location Expressions for details. | |
expr | false | This attribute must not occur in an <assign> element that has children. | value expression | none | Any valid value expression | An expression returning the value to be assigned. See 5.10.3 Legal Data Values and Value Expressions for details. |
The children of the <assign>element provide an in-line specification of the legal data value (see 5.10.3 Legal Data Values and Value Expressions ) to be inserted into the datamodel at the specified location.
A conformant SCXML document MUST specify either "expr" or children of <assign>, but not both.
Assignment
to
a
data
model
is
done
by
using
a
location
expression
to
denote
the
part
of
the
data
model
where
the
insertion
is
to
be
made.
If
the
location
expression
does
not
denote
a
valid
location
in
the
datamodel
or
if
the
value
specified
(
by
(by
'expr'
or
children)
is
not
a
legal
value
for
the
location
specified,
the
processor
SCXML
Processor
MUST
place
the
error
error.execution
'error.execution'
in
the
internal
event
queue.
Otherwise,
the
processor
SCXML
Processor
MUST
place
the
specified
value
at
the
specified
location.
Note
that
the
nature
of
the
insertion
and
the
definition
of
a
legal
value
depends
on
the
data
model
language
used.
Note
also
that
datamodels
MAY
support
additional
attributes
for
<assign>
beyond
those
specified
here.
See
D
Data
Models
for
details.
[This section is normative.]
The <validate> element causes the datamodel to be validated.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
location | false | location expression | none | Any valid location expression. | The location of the subtree to validate. If it is not present, the entire datamodel is validated. See 5.10.2 Location Expressions for details. | |
schema | false | URI | none | Any valid URI | The location of the schema to use for validation. If this attribute is not present, the schema specified in the top-level <datamodel> is used. |
The
SCXML
processor
Processor
MUST
validate
the
datamodel
only
when
instructed
to
do
so
by
the
<validate>
element.
A
valid
SCXML
document
containing
the
<validate>
element
MUST
specify
a
schema
with
the
'schema'attribute
'schema'
attribute
of
the
<validate>
element
or
with
the
'schema'
attribute
of
the
top-level
<datamodel>
element
(or
with
both).
If
the
<validate>
element
specifies
a
schema,
the
processor
SCXML
Processor
MUST
use
this
schema
to
validate
the
datamodel.
Otherwise,
it
MUST
use
the
value
specified
in
the
<datamodel>
element.
[This section is normative.]
A wrapper element holding data to be returned when a <final> state is entered.
A
conformant
SCXML
document
MUST
specify
either
a
single
<content>
element
or
one
or
more
<param>
elements
as
children
of
<donedata>,
but
not
both.
.
In
cases
where
the
SCXML
processor
Processor
generates
a
'done'
event
upon
entry
into
the
final
state,
it
MUST
evaluate
the
<donedata>
elements
<param>
or
<content>
children
and
place
the
resulting
data
specified
by
this
element
in
the
_event.data
field,
but
field.
The
exact
format
of
that
data
will
be
determined
by
the
datamodel
(see
D
Data
Models
for
details).
In
other
cases
(namely
when
the
<final>
element
is
a
child
of
<scxml>
and
the
state
machine
has
not
been
triggered
by
<invoke>),
the
SCXML
processor
Processor
SHOULD
return
the
data
to
the
environment
in
an
implementation-dependent
manner.
[This section is normative.]
A
container
element
holding
in-line
data
to
be
passed
to
an
external
service.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
expr | false | must not occur with child content | Value expression | none | Any valid value expression | A value expression. See 5.10.3 Legal Data Values and Value Expressions for details. |
In
a
A
conformant
SCXML
document,
document
MUST
NOT
specify
both
the
'expr'
attribute
and
child
elements
content.
When
present,
the
children
of
<content>
contain
arbitrary
markup
which
MAY
consist
of
text,
XML
from
any
namespace,
or
a
mixture
of
both.
The
use
of
this
markup
the
<content>
element
depends
on
the
context
in
which
the
<content>
element
it
occurs.
See
5.6
<donedata>
,
6.2
<send>
and
6.4
<invoke>
for
details.
When
the
SCXML
Processor
evaluates
the
<content>
element,
if
the
'expr'
value
expression
is
present,
the
Processor
MUST
evaluate
it
and
use
the
result
as
the
value
of
the
<content>
element.
If
the
evaluation
of
'expr'
produces
an
error,
the
Processor
MUST
place
error.execution
in
the
internal
event
queue
and
use
the
empty
string
as
the
value
of
the
<content>
element.
If
the
'expr'
attribute
is
not
present,
the
Processor
MUST
treat
the
children
of
<content>
as
a
string
literal
and
use
them
as
the
value.
For
the
use
of
namespaces
inside
<content>,
see
G.7
Inline
Content
and
Namespaces
.
[This section is normative.]
The
<param>
tag
provides
a
general
way
of
identifying
a
name/key
and
a
dynamically
calcuated
calculated
value,
which
can
be
passed
to
an
external
service
or
included
in
an
event.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
name | true | NMTOKEN | none | A string literal | The name of the key. | |
expr | false | May not occur with 'location' | value expression | none | Valid value expression | A value expression (see 5.10.3 Legal Data Values and Value Expressions ) that is evaluated to provide the value. |
location | false | May not occur with 'expr' | location expression | none | Valid location expression | A location expression (see 5.10.2 Location Expressions ) that specifies the location in the datamodel to use as the value. |
A
conformant
SCXML
document
MUST
specify
either
the
'expr'
attribute
of
<param>
or
the
'location'
attribute,
but
MUST
NOT
specify
both.
If
the
'location'
attribute
does
not
refer
to
a
valid
location
in
the
data
model,
or
if
the
evaluation
of
the
'expr'
produces
an
error,
the
processor
SCXML
Processor
MUST
place
the
error
error.execution
'error.execution'
on
the
internal
event
queue
and
MUST
ignore
the
name
and
value.
Otherwise
the
use
of
the
name
and
value
depends
on
the
context
in
which
the
<param>
element
occurs.
See
5.6
<donedata>
,
6.2
<send>
and
6.4
<invoke>
for
details.
[This section is normative.]
The <script> element adds scripting capability to the state machine.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
src | false | May not occur if the element has children. | none | A valid URI | Gives the location from which the script should be downloaded. |
The
children
child
content
of
the
<script>
element
represent
represents
the
script
code
to
be
executed.
A conformant SCXML document MUST specify either the 'src' attribute or child content, but not both. If 'src' is specified, the SCXML Processor MUST download the script from the specified location at load time. If the script can not be downloaded within a platform-specific timeout interval, the document is considered non-conformant, and the platform MUST reject it.
The SCXML Processor MUST evaluate any <script> element that is a child of <scxml> at document load time. It MUST evaluate all other <script> elements as part of normal executable content evaluation.
In a conformant SCXML document, the name of any script variable MAY be used as a location expression (see 5.10.2 Location Expressions ).
For an example of a data model incorporating scripting, see D.2 The ECMAScript Data Model .
[This section is normative.]
SCXML contains three types of expressions, as described below. Different datamodels will support different languages for these expression types, but certain properties of the expressions are constant across languages and are defined here.
The
SCXML
processor
Processor
MAY
optimize
expression
evaluation.
Thus
the
SCXML
processor
MAY
not
evaluate
expressions
evaluation
as
often
long
as
indicated
the
resulting
behavior
is
identical
to
that
defined
by
the
algorithm
in
A
Algorithm
for
SCXML
Interpretation
or
at
the
same
points
in
the
algorithm.
.
When "late" data binding is used, accessing data substructure in expressions before the corresponding <data> element is loaded MUST yield the same execution-time behavior as accessing non-existent data substructure in a loaded <data> instance. Such behavior is defined by the data expression language in use.
Conditional
expressions
are
used
inside
the
'cond'
attribute
of
<transition>,
<if>
and
<elseif>.
The
SCXML
processor
Processor
MUST
insure
ensure
that
boolean
expressions
do
not
contain
side
effects
that
would
effect
the
datamodel
or
the
execution
of
the
state
machine.
If
a
conditional
expression
cannot
be
evaluated
as
a
boolean
value
('true'
or
'false')
or
if
its
evaluation
causes
an
error,
the
SCXML
processor
Processor
MUST
treat
the
expression
as
if
it
evaluated
to
'false'
and
MUST
place
the
error
'error.execution'
in
the
internal
event
queue.
The
set
of
operators
in
conditional
expressions
varies
depending
on
the
datamodel,
but
all
datamodels
MUST
support
the
'In()'
predicate,
which
takes
a
stateID
state
ID
as
its
argument
and
returns
true
if
the
state
machine
is
in
that
state.
This
predicate
allows
coordination
among
parallel
regions.
Location
expressions
are
used
to
specify
a
location
in
the
datamodel
as
part
of
the
<assign>element.
The
exact
nature
of
a
location
depends
on
the
datamodel.
For
example,
in
the
XPath
datamodel
(
D.3
The
XPath
Data
Model
),
the
underlying
data
structure
is
an
a
collection
of
XML
tree
nodes
specified
by
individual
<data>
elements
and
the
set
of
valid
locations
consists
of
the
existing
nodes
and
nodesets
in
the
tree.
these
data
nodes.
If
a
location
expression
cannot
be
evaluated
to
yield
a
valid
location,
the
SCXML
processor
MUST
place
the
error
error.execution
'error.execution'
in
the
internal
event
queue.
A
data
model
definition
contains
a
specification
of
the
underlying
data
structure.
For
example,
the
XPath
datamodel
(
D.3
The
XPath
Data
Model
)
defines
the
data
structure
to
be
an
a
collection
of
XML
tree.
nodes
specified
by
individual
<data>
elements.
Such
a
specification
of
the
data
structure
implicitly
defines
a
set
of
"legal
data
values",
namely
the
objects
that
can
be
part
of
such
a
data
structure.
For
an
XML
data
model,
the
set
of
legal
data
values
consists
of
XML
trees
data
nodes
and
subtrees,
descendants,
plus
strings
(as
values
of
attributes
or
text
children).
In
conjunction
with
this,
the
datamodel
definition
specifies
a
set
of
value
expressions
which
can
be
evaluated
at
runtime
to
return
legal
data
values.
If
a
value
expression
does
not
return
a
legal
data
value,
the
SCXML
processor
Processor
MUST
place
the
error
error.execution
'error.execution'
in
the
internal
event
queue.
The
SCXML
processor
Processor
MAY
reject
documents
containing
syntactically
ill-formed
expressions
at
document
load
time,
or
it
MAY
wait
and
place
error.execution
'error.execution'
in
the
internal
event
queue
at
runtime
when
the
expressions
are
evaluated.
If
the
processor
waits
until
it
evaluates
the
expressions
at
runtime
to
raise
errors,
it
MUST
raise
errors
caused
by
expressions
returning
illegal
values
at
the
points
at
which
A
Algorithm
for
SCXML
Interpretation
indicates
that
the
expressions
are
to
be
evaluated.
Note
that
this
requirement
holds
even
if
the
implementation
is
optimizing
expression
evaluation.
[This section is normative.]
The SCXML Processor MUST maintain a protected portion of the data model containing information that can be useful to applications. We refer to the items in this special part of the data model as 'system variables'. Implementations MUST provide the following system variables, and MAY support others.
The set of system variables may be expanded in future versions of this specification. Variable names beginning with '_' are reserved for system use. A conformant SCXML document MUST NOT contain ids beginning with '_' in the <data> element. Platforms MUST place all platform-specific system variables under the '_x' root.
The
concrete
realization
of
these
variables
in
a
specific
data
model
depends
on
the
language
used.
For
the
exact
location
of
these
variables
in
an
XML
data
model,
see
D.3
The
XPath
Data
Model
.
The
Processor
MUST
cause
any
attempt
to
change
the
value
of
a
system
variable
to
fail
and
MUST
place
the
error
error.execution
'error.execution'
on
the
internal
event
queue
when
such
an
attempt
is
made.
Events have an internal structure which is reflected in the _event variable. This variable can be accessed to condition transitions (via boolean expressions in the 'cond' attribute) or to update the datamodel (via <assign>), etc.
The
SCXML
Processor
MUST
insure
ensure
that
the
following
fields
are
present
in
all
events,
whether
internal
or
external.
[This section is informative.]
The External Communications capability allows an SCXML session to send and receive events from external entities, and to invoke external services. 6.2 <send> provides "fire and forget" capability to deliver events and data to any destination, including other SCXML sessions. The 'delay' attribute allows for deferred event delivery and can be used to implement a timer. The details of event transport as well as the format of the event and data are determined by the Event I/O Processor selected. Each implementation will support one or more such processor, and the author of the SCXML markup can choose the one that is appropriate for the type of endpoint he is trying to reach.
6.4 <invoke> offers a more tightly coupled form of communication, specifically the ability to trigger a platform-defined service and pass data to it. It and its child <finalize> are useful in states that model the behavior of an external service. The <invoke> element is executed after the state's <onentry> element and causes an instance of the external service to be created. The <param> and <content> elements and the 'namelist' attribute can be used to pass data to the service. Any events that are received by the state machine from the invoked component during the invocation are preprocessed by the <finalize> handler before transitions are selected. The <finalize> code is used to normalize the form of the returned data and to update the data model before the transitions' "event" and "cond" clauses are evaluated.
When parallel states invoke the same external service concurrently, separate instances of the external service will be started. They can be distinguished by ids which are associated with them. Similarly, the ids contained in the events returned from the external services can be used to determine which events are responses to which invocation. Each event that is returned will be processed only by the <finalize> in the state that invoked it, but that event is then processed like any other event that the state machine receives. The finalize code can thus be thought of as a preprocessing stage that applies before the event is added to the event queue. Note that the event will be passed to all parallel states to check for transitions.
Since an invocation will be canceled when the state machine leaves the invoking state, it does not make sense to start an invocation in a state that will be exited immediately. Therefore the <invoke> element is executed upon entry into the state, but only after checking for eventless transitions and transitions driven by pending internal events. If any such enabled transition is found , it is taken and the state is exited immediately, without triggering the invocation. Thus invocations are triggered only when the state machine has reached a stable configuration, i.e., one that it will be staying in while it waits for external events. (See A Algorithm for SCXML Interpretation for details.)
[This section is normative.]
<send> is used to send events and data to external systems, including external SCXML Interpreters, or to raise events in the current SCXML session.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
event | false |
Must
not
occur
with
'eventexpr'.
If
the
type
is
|
EventType.datatype | none | A string indicating the name of message being generated. See B Schema for details on the data type. | |
eventexpr | false |
Must
not
occur
with
'event'.
If
the
type
is
|
Value expression | none | A dynamic alternative to 'event'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <send> element is evaluated and treat the result as if it had been entered as the value of 'event'. | |
target | false | Must not occur with 'targetexpr' | URI | none | A valid target URI | The unique identifier of the message target that the platform should send the event to. See 6.2.4 The Target of Send for details. |
targetexpr | false | Must not occur with 'target' | Value expression | none | An expression evaluating to a valid target URI | A dynamic alternative to 'target'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <send> element is evaluated and treat the result as if it had been entered as the value of 'target'. |
type | false | Must not occur with 'typeexpr' |
|
none |
|
|
typeexpr | false | Must not occur with 'type' | value expression | none | A dynamic alternative to 'type'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <send> element is evaluated and treat the result as if it had been entered as the value of 'type'. | |
id | false | Must not occur with 'idlocation'. | xml:ID | none | Any valid token | A string literal to be used as the identifier for this instance of <send>. See 3.14 IDs for details. |
idlocation | false | Must not occur with 'id'. | Location expression | none | Any valid location expression | Any location expression evaluating to a data model location in which a system-generated id can be stored. See below for details. for details. |
delay | false | Must not occur with 'delayexpr' or when the attribute 'target' has the value "_internal". | Duration.datatype | None | A time designation as defined in CSS2 [CSS2] format | Indicates how long the processor should wait before dispatching the message. See B Schema for details on the data type. |
delayexpr | false | Must not occur with 'delay' or when the attribute 'target' has the value "_internal". | Value expression | None | A value expression which returns a time designation as defined in CSS2 [CSS2] format | A dynamic alternative to 'delay'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <send> element is evaluated and treat the result as if it had been entered as the value of 'delay'. |
namelist | false | Must not be specified in conjunction with the <content> element. | List of location expressions | none | List of data model locations | A space-separated list of one or more data model locations to be included with the message. See 5.10.2 Location Expressions for details. |
A
conformant
SCXML
document
MUST
specify
either
exactly
one
of
'event',
'eventexpr'
or
in-line
content.
A
conformant
document
MUST
NOT
specify
'event'
in
conjunction
with
the
inline
content.
and
<content>.
A
conformant
document
MUST
NOT
specify
both
"namelist"
and
or
<param>
with
<content>.
If 'idlocation' is present, the SCXML Processor MUST generate an id when the parent <send> element is evaluated and store it in this location. See 3.14 IDs for details.
If
a
delay
is
specified
via
'delay'
or
'delayexpr',
the
SCXML
Processor
MUST
interpret
the
character
string
as
a
time
interval.
It
MUST
dispatch
the
message
only
when
the
delay
interval
elapses.
(Note
that
the
evaluation
of
the
send
tag
will
return
immediately.)
The
Processor
MUST
evaluate
all
arguments
to
<send>
when
the
<send>
element
is
evaluated,
and
not
when
the
message
is
actually
dispatched.
If
the
SCXML
session
terminates
before
the
delay
interval
has
elapsed,
the
SCXML
Processor
MUST
discard
the
message
without
attempting
to
deliver
it.
The target of the <send> operation specifies the destination of the event. The target is defined by either the 'target' or the 'targetexpr' attribute. In most cases, the format of the target depends on the type of the target (for example a SIP URL for SIP-INFO messages or a HTTP URL for Web Services). In addition, this specification defines the following special values, which SCXML Processors MUST support:
If
neither
the
'target'
nor
the
'targetexpr'
attribute
is
specified,
the
SCXML
Processor
MUST
add
the
event
will
be
added
to
the
external
event
queue
of
the
sending
session.
If
the
value
of
the
'target'
or
'targetexpr'
attribute
is
not
supported
or
invalid,
the
Processor
MUST
place
the
error
error.execution
on
the
internal
event
queue.
If
it
is
unable
to
reach
dispatch
the
target,
message,
the
Processor
MUST
place
the
error
error.communication
on
the
internal
event
queue.
The
type
of
the
<send>
operation
specifies
the
method
that
the
SCXML
processor
MUST
use
to
deliver
the
message
to
its
target.
A
conformant
SCXML
document
MAY
use
either
the
'type'
or
the
'typeexpr'
attribute
to
define
the
type.
If
neither
the
'type'
nor
the
'typeexpr'
is
defined,
the
SCXML
Processor
MUST
assume
the
default
value
of
'scxml.
http://www.w3.org/TR/scxml/#SCXMLEventProcessor.
If
the
SCXML
Processor
does
not
support
the
type
that
is
specified,
it
MUST
place
the
event
error.execution
on
the
internal
event
queue.
SCXML Processors MUST support the following type:
Value | Details |
---|---|
|
Target is an SCXML session. The transport mechanism is platform-specific. |
For
details
on
the
'scxml'
http://www.w3.org/TR/scxml/#SCXMLEventProcessor
type,
see
E.1
SCXML
Event
I/O
Processor
.
Support for HTTP POST is optional, however Processors that support it must use the following value for the "type" attribute:
Value | Details |
---|---|
|
Target is a URL. Data is sent via HTTP POST |
For
details
on
the
'basichttp'
http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor
type,
see
E.2
Basic
HTTP
Event
I/O
Processor
.
Support for DOM event delivery is optional, however Processors that support it must use the following value for the "type" attribute:
Value | Details |
---|---|
|
Target is a node in the current document, which may contain markup from multiple namespaces. A DOM event will be targeted at that node. |
For
details
on
the
'DOM'
http://www.w3.org/TR/scxml/#DOMEventProcessor
type,
see
E.3
DOM
Event
I/O
Processor
.
Processors
MAY
support
other
types
such
as
web-services,
SIP
or
basic
HTTP
GET.
However,
When
they
do
so,
they
SHOULD
assign
such
types
names
beginning
with
"x-"
the
URI
of
the
description
of
the
relevant
Event
I/O
Processor.
Processors
MAY
define
short
form
notations
as
an
authoring
convenience
(e.g.,
"scxml"
as
equivalent
to
signify
that
they
are
platform
dependent.
http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor).
The sending SCXML Interpreter MUST not alter the content of the <send> and MUST include it in the message that it sends to the destination specified in the target attribute of <send>.
Note that the document author can specify the message content in one of two mutually exclusive ways:
<datamodel> <data id="target" expr="'tel:+18005551212'"/> <data id="content" expr="'http://www.example.com/mycontent.txt'"/> </datamodel> ... <send target="target" type="x-messaging" event="fax.SEND" namelist="content"/>
<send target="csta://csta-server.example.com/" type="x-csta"> <content> <csta:MakeCall> <csta:callingDevice>22343</callingDevice> <csta:calledDirectoryNumber>18005551212</csta:calledDirectoryNumber> </csta:MakeCall> </content> </send>
Note that the absence of any error events does not mean that the event was successfully delivered to its target, but only that the platform was able to dispatch the event.
[This section is normative.]
The <cancel> element is used to cancel a delayed <send> event. The SCXML Processor MUST NOT allow <cancel> to affect events that were not raised in the same document. The Processor SHOULD make its best attempt to cancel the delayed event. Note, however, that it can not be guaranteed to succeed, for example if the event has already been delivered by the time the <cancel> tag executes.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
sendid | false | Must not occur with sendidexpr. | IDREF | none | The ID of a delayed event | The ID of the event which is to be canceled. |
sendidexpr | false | Must occur with sendid. | Value Expression | none | Any expression that evaluates to the ID of a delayed event | A dynamic alternative to 'sendid'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <cancel> element is evaluated and treat the result as if it had been entered as the value of 'sendid'. |
A conformant SCXML document MUST specify exactly one of sendid or sendidexpr.
[This section is normative.]
The <invoke element is used to create an instance of an external service.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
type | false | Must not occur with the 'typeexpr' attribute. |
|
none |
|
A
|
typeexpr | false | Must not occur with the 'type' attribute. | value expression | none |
Any
value
expression
that
evaluates
to
a
|
A dynamic alternative to 'type'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <invoke> element is evaluated and treat the result as if it had been entered as the value of 'type'. |
src | false | Must not occur with the 'srcexpr' attribute or the <content> element. | URI | None | Any URI. | A URI to be passed to the external service. See below for details. |
srcexpr | false | Must not occur with the 'src' attribute or the <content> element. | Value expression | None | Any expression evaluating to a valid URI. | A dynamic alternative to 'src'. If this attribute is present, the SCXML Processor MUST evaluate it when the parent <invoke> element is evaluated and treat the result as if it had been entered as the value of 'src'. |
id | false | Must not occur with the 'idlocation' attribute. | ID | none | Any valid token | A string literal to be used as the identifier for this instance of <invoke>. See 3.14 IDs for details. |
idlocation | false | Must not occur with the 'id' attribute. | Location expression | none | Any valid location expression | Any data model expression evaluating to a data model location. See 5.10.2 Location Expressions for details. |
namelist | false | Must not occur with the <content> element. | List of location expressions | none | List of data model locations | A space-separated list of zero or more data model locations to be passed to the invoked service. See See 6.4.4 Data Sharing and 5.10.2 Location Expressions for details. |
autoforward | false | boolean | false | true or false | A flag indicating whether to forward events to the invoked process. See below for details. |
A conformant SCXML Document MUST NOT specify more than one of 'src', <param>, or <content>. However it MAY specify <param> multiple times.
Platforms
MUST
support
'scxml'
http://www.w3.org/TR/scxml/
as
a
value
for
the
'type'
attribute.
Platforms
MAY
support
'vxml2',
http://www.w3.org/TR/voicexml21/,
which
indicates
a
VoiceXML
2.x
2.1
interpreter,
'vxml3'
http://www.w3.org/TR/voicexml30/,
which
indicates
a
VoiceXML
3.x
interpreter,
and
'ccxml',
http://www.w3.org/TR/ccxml/,
which
indicates
a
CCXML
1.0
interpreter.
Platforms
MAY
support
additional
values,
but
they
SHOULD
name
assign
them
the
values
beginning
with
"x-"
URI
of
a
description
of
the
relevant
service.
Processors
MAY
define
short
form
notations
as
an
authoring
convenience
(e.g.,
"scxml"
as
equivalent
to
signify
that
they
are
platform
dependent.
http://www.w3.org/TR/scxml/).
A conformant SCXML document MAY specify either the 'id' or 'idlocation' attribute, but MUST NOT specify both. If the 'idlocation' attribute is present, the SCXML Processor MUST generate an id automatically when the <invoke> element is evaluated and store it in the location specified by 'idlocation'. (In the rest of this document, we will refer to this identifier as the "invokeid", regardless of whether it is specified by the author or generated by the platform). The automatically generated identifier MUST have the form stateid.platformid , where stateid is the id of the state containing this element and platformid is automatically generated. platformid MUST be unique within the current session.
When
the
<invoke>
element
is
executed,
the
SCXML
Processor
MUST
start
a
new
logical
instance
of
the
external
service
specified
in
'type'
or
'typexpr',
passing
it
the
URL
specified
by
'src'
or
the
data
specified
by
<content>,
or
<param>.
The
service
instance
MAY
be
local
or
remote.
In
addition
to
the
explicit
arguments,
the
Processor
MUST
keep
track
of
the
unique
invokeid
and
insure
ensure
that
it
is
included
in
all
events
that
the
invoked
service
returns
to
the
invoking
session.
When the 'autoforward' attribute is set to true, the SCXML Processor MUST send an exact copy of every external event it receives to the invoked process. All the fields specified in 5.11.1 The Internal Structure of Events MUST have the same values in the forwarded copy of the event. The SCXML Processor MUST forward the event at the point at which it removes it from the external event queue of the invoking session for processing. See A Algorithm for SCXML Interpretation for details.
The external service MAY return multiple events while it is processing. If there is a <finalize> handler in the instance of <invoke> that created the service that generated the event, the SCXML Processor MUST execute the code in that <finalize> handler right before it removes the event from the event queue for processing. It MUST NOT execute the <finalize> handler in any other instance of <invoke>. Once the external service has finished processing it MUST return a special event 'done.invoke. id ' to the external event queue of the invoking process, where id is the invokeid for the corresponding <invoke> element. The external service MUST NOT generate any other events after this done event. If the invoking session takes a transition out of the state containing the <invoke> before it receives the 'done.invoke. id ' event, the SCXML Processor MUST automatically cancel the invoked component and stop its processing. The cancel operation MUST act as if it were the final <onexit> handler in the invoking state.
Invoked
services
of
type
'scxml',
'ccxml',
'vxml2'
http://www.w3.org/TR/scxml/,
http://www.w3.org/TR/ccxml/,
http://www.w3.org/TR/voicexml30/,
or
'vxml3'
http://www.w3.org/TR/voicexml21/
MUST
interpret
values
specified
by
the
<content>
element
or
'src'
attribute
as
markup
to
be
executed.
Similarly,
they
MUST
interpret
values
specified
by
<param>
element
or
'namelist'
attribute
as
values
that
are
to
be
injected
into
their
data
models.
For
targets
of
other
invoked
service
types,
the
interpretation
of
<param>
and
<content>
elements
and
the
'src'
and
'namelist'
attributes
is
platform-specific.
However,
these
services
MUST
treat
values
specified
by
<param>
and
namelist
identically.
They
MUST
also
treat
values
specified
by
'src'
and
<content>
identically.
The implementation of <invoke>, including communication between parent and child processes, is platform-specific, but the following requirements hold in the case where the invoked process is itself an SCXML session:
[This section is informative.]
The invoked external resource is logically separate from the state machine that invokes it and does not share data with it unless the author explicitly requests this with the <param> or <content> elements and/or the 'src' and 'namelist' attributes.
The invoked and invoking process can also communicate via events. In addition to automatic forwarding specified by the 'autoforward' attribute. SCXML scripts can also use the <send> tag to send messages to the child process on an ad-hoc basis. The 'type' attribute of <send> is set to the same value as was used in the original <invoke>, while the target has the special form #_ invokeid , where invokeid is the identifier corresponding to the original <invoke> tag. For example, in a document using ECMAScript as the data model, the following code would invoke a VXML session:
<invoke type="vxml" idlocation="myInvoke"/><invoke type="http://www.w3.org/TR/voicexml21/" idlocation="myInvoke"/>
In this case, the unique invoke identifier has been stored in the data model location MyInvoke. Since the target attribute is an expression which is evaluated, the following code will extract that identifier and send a message to the invoked VXML session:
<send type="vxml" targetexpr="'#' + myInvoke"/><send type="http://www.w3.org/TR/voicexml21/" targetexpr="'#' + myInvoke"/>
Finally, in the case where the invoked external service is an SCXML session, it can use <send> with the special target '_parent' and type 'scxml' to send events, possibly containing data, to the invoking session.
[This section is normative.]
The <finalize> element enables an invoking session to update its data model with data contained in events returned by the invoked session. <finalize> contains executable content that is executed whenever the external service returns an event after the <invoke> has been executed. This content is applied before the system looks for transitions that match the event. Within the executable content, the system variable '_event' can be used to refer to the data contained in the event which is being processed.In the case of parallel states, only the finalize code in the original invoking state is executed.
In a conformant SCXML document, the executable content inside <finalize> MUST NOT raise events or invoke external actions. In particular, the <send> and <raise> elements MUST NOT occur.
If one or more elements of executable content is specified, the SCXML Processor MUST execute them each time an event is received from the child process that was created by the parent <invoke> element. The Processor MUST execute them right before the event is pulled off the external event queue for processing. The Processor MUST NOT execute them at any other time or in response to any other events.
If
no
executable
content
is
specified,
the
SCXML
Processor
MUST
update
the
data
model
each
time
an
event
is
received
from
the
child
process
that
was
created
by
the
parent
<invoke>
element.
Specifically
if
the
parent
<invoke>
element
contains
a
'namelist'
attribute
or
one
or
more
<param>
children
containing
'location'
attributes,
then
for
each
item
in
the
'namelist'
attribute
and
each
such
<param>
element,
the
Processor
MUST
update
the
corresponding
location
with
any
return
values
value
that
have
has
a
name
that
matches
the
'location'
attribute
name
of
a
<param>
element
inside
the
<invoke>.
'namelist'
item
or
the
'name'
of
the
<param>
element.
Thus
the
effect
of
an
<invoke>
with
an
empty
<finalize>
element
and
either
a
'namelist'
attribute
or
a
<param>
element
with
a
'location'
attribute
coupled
with
an
empty
<finalize>
element
is
first
to
send
the
part
of
the
data
model
specified
by
'namelist'
or
'location'
to
the
invoked
component
and
then
to
update
that
part
of
the
data
model
with
the
any
returned
values.
values
that
have
the
same
name.
Note
that
the
automatic
update
does
not
take
place
if
the
<finalize>
element
is
absent
as
opposed
to
empty.
In the example below, a state machine using an ECMAScript data model invokes a clock object that returns the current time in a ping event with an XML payload that includes the currentSecond, currentMinute, currentHour (1-12), and an isAm flag. <finalize> maps this data into an ECMAScript date object that is used in the condition of a transition. Thus <finalize> normalizes the data before the conditions on transitions are evaluated.
<scxml version="1.0" datamodel="ecmascript"> .... <state id="getTime"> <transition event="ping" cond="time.getHours() > 17 || time.getHours() < 9" target="storeClosed"/> <transition event="ping" target="takeOrder"/> <datamodel> <data id="time" expr="new Date()"/> </datamodel> <invoke id="timer" type="x-clock" src="clock.pl"> <finalize> <script> time.setSeconds(_event.data.currentSecond); time.setMinutes(_event.data.currentMinute); time.setHours(_event.data.currentHour + (_event.isAm ? 0 : 12) - 1); </script> </finalize> </invoke> </state> ....
This
section
presents
contains
a
normative
algorithm
for
the
interpretation
of
an
SCXML
document.
Implementations
are
free
to
implement
SCXML
interpreters
in
any
way
they
choose,
but
they
must
MUST
behave
as
if
they
were
using
the
algorithm
defined
here.
The fact that SCXML implements a variant of the Statechart formalism does not as such determine a semantics for SCXML. Many different Statechart variants have been proposed, each with its own semantics. This section presents an informal semantics of SCXML documents, as well as a normative algorithm for the interpretation of SCXML documents.
[This section is informative.]
The following definitions and highlevel principles and constraint are intended to provide a background to the normative algorithm, and to serve as a guide for the proper understanding of it.
We state here some principles and constraints, on the level of semantics, that SCXML adheres to:
[This section is normative.]
This section presents a normative algorithm for the interpretation of SCXML documents. Implementations are free to implement SCXML interpreters in any way they choose, but they must behave as if they were using the algorithm defined here. Note that the algorithm assumes a Lisp-like semantics in which the empty Set null is equivalent to boolean 'false' and all other entities are equivalent to 'true'.
These are the abstract datatypes that are used in the algorithm.
datatype Listfunction
head() // Returns the head of the listfunction
tail() // Returns the tail of the listfunction
append(l) // Returns the list appended with lfunction
filter(f) // Returns the list of elements that satisfy the predicate ffunction
some(f) // Returns true if some element in the list satisfies the predicate ffunction
every(f) // Returns true if every element in the list satisfies the predicate f datatype OrderedSetprocedure
add(e) // Adds e to the set if it is not already a memberprocedure
delete(e) // Deletes e from the setfunction
member(e) // Is e a member of set?function
isEmpty() // Is the set empty?function
toList() // Converts the set to a list that reflects the order in which elements were originally added.procedure
clear() // Remove all elements from the set (make it empty)diff(set2) // Returns an OrderedSet containing all members of OrderedSet that are not in set2, preserving the original set order.datatype Queueprocedure
enqueue(e) // Puts e last in the queuefunction
dequeue() // Removes and returns first element in queuefunction
isEmpty() // Is the queue empty? datatype BlockingQueueprocedure
enqueue(e) // Puts e last in the queuefunction
dequeue() // Removes and returns first element in queue, blocks if queue is empty
The following variables are global from the point of view of the algorithm. Their values will be set in the procedureinterpret().
global configurationglobal previousConfigurationglobal statesToInvoke global datamodel global internalQueue global externalQueue global historyValueglobal continueglobal running global binding
The following binary predicates are used for determining the order in which states are entered and exited.
name="entryOrder">entryOrder // Ancestors precede descendants, with document order being used to break ties name="entryOrder">entryOrder
// Ancestors precede descendants, with document order being used to break ties (Note:since ancestors precede descendants, this is equivalent to document order.)name="exitOrder">exitOrder // Descendants precede ancestors, with reverse document order being used to break ties name="exitOrder">exitOrder
// Descendants precede ancestors, with reverse document order being used to break ties (Note: since descendants follow ancestors, this is equivalent to reverse document order.)
This section defines the procedures and functions that make up the core of the SCXML interpreter.
procedure
interpret(scxml,id)
The purpose of this procedure is to initialize the interpreter and to start processing. It is called with a parsed representation of an SCXML document.
In
order
to
interpret
an
SCXML
document,
first
(optionally)
validate
the
document,
and
throw
an
exception
if
validation
fails.
Then
convert
initial
attributes
to
<initial>
container
children
with
transitions
to
the
state
specified
by
the
attribute
(such
attribute.
(This
step
is
done
purely
to
simplify
the
statement
of
the
algorithm
and
has
no
effect
on
the
system's
behavior.
Such
transitions
will
not
contain
any
executable
content).
Then
(optionally)
validate
the
resulting
SCXML,
and
throw
an
exception
if
validation
fails.
Create
an
empty
configuration
complete
with
a
new
populated
instance
of
the
data
model
and
a
execute
the
global
scripts.
Create
the
two
queues
to
handle
events
and
set
the
global
continue
running
variable
to
true.
Finally
call
enterState
enterStates
on
the
initial
transition
that
is
a
child
of
scxml
and
start
the
interpreter's
event
loop.
procedure interpret(doc):expandScxmlSource(doc)if not valid(doc): failWithError() expandScxmlSource(doc) configuration = new OrderedSet()previousConfiguration = new OrderedSet()statesToInvoke = new OrderedSet() datamodel = new Datamodel(doc) executeGlobalScriptElements(doc) internalQueue = new Queue() externalQueue = new BlockingQueue()continue = truerunning = true binding = doc.binding if binding == "early": initializeDatamodel(datamodel, doc)enterState([doc.initial.transition]) startEventLoop() procedure startEventLoop() Upon entering the state machine, we take all internally enabled transitions, namely those that either don't require an event or that are triggered by internal events. (Internal events can only be generated by the state machine itself.) When all such transitions have been taken, we move to the main event loop, which is driven by external events. procedure startEventLoop(): initialStepComplete = false until initialStepComplete: enabledTransitions = selectEventlessTransitions() if enabledTransitions.isEmpty(): if internalQueue.isEmpty(): initialStepComplete = true else: internalEvent = internalQueue.dequeue() datamodel["event"] = internalEvent enabledTransitions = selectTransitions(internalEvent) if not enabledTransitions.isEmpty(): microstep(enabledTransitions.toList())executeTransitionContent([doc.initial.transition]) enterStates([doc.initial.transition]) mainEventLoop()
procedure
mainEventLoop()
This
loop
runs
until
we
enter
a
top-level
final
state
or
an
external
entity
cancels
processing.
In
either
case
'continue'
'running'
will
be
set
to
false
(see
EnterStates,
below,
for
termination
by
entering
a
top-level
final
state.)
At
the
top
of
the
loop,
we
have
either
just
entered
the
state
machine,
or
we
have
just
processed
an
external
event.
Each
iteration
through
the
loop
consists
of
three
four
main
steps:
1)
1)Take
any
internally
enabled
transitions,
namely
those
that
don't
require
an
event
or
that
are
triggered
by
an
internal
event.
2)
execute
any
<invoke>
tags
for
states
that
we
entered
on
the
last
iteration
through
the
loop
2)
Wait
3)
repeat
step
1
to
handle
any
errors
raised
by
the
<invoke>
elements.
4)
When
the
internal
event
queue
is
empty,
wait
for
an
external
event
and
then
execute
any
transitions
that
it
triggers.
However
special
preliminary
processing
is
applied
to
the
event
if
the
state
has
executed
any
<invoke>
elements.
First,
if
this
event
was
generated
by
an
invoked
process,
apply
<finalize>
processing
to
it.
Secondly,
if
any
<invoke>
elements
have
autoforwarding
set,
forward
the
event
to
them.
These
steps
apply
before
the
transitions
are
taken.
3)
Take
any
subsequent
internally
enabled
transitions,
namely
those
that
don't
require
an
event
or
that
are
triggered
by
an
internal
event.
This event loop thus enforces run-to-completion semantics, in which the system process an external event and then takes all the 'follow-up' transitions that the processing has enabled before looking for another external event. For example, suppose that the external event queue contains events ext1 and ext2 and the machine is in state s1. If processing ext1 takes the machine to s2 and generates internal event int1, and s2 contains a transition t triggered by int1, the system is guaranteed to take t, no matter what transitions s2 or other states have that would be triggered by ext2. Note that this is true even though ext2 was already in the external event queue when int1 was generated. In effect, the algorithm treats the processing of int1 as finishing up the processing of ext1.
procedure mainEventLoop():while continue:while running: enabledTransitions = null stable = false # Here we handle eventless transitions and transitions # triggered by internal events until machine is stable while running and not stable: enabledTransitions = selectEventlessTransitions() if enabledTransitions.isEmpty(): if internalQueue.isEmpty(): stable = true else: internalEvent = internalQueue.dequeue() datamodel["_event"] = internalEvent enabledTransitions = selectTransitions(internalEvent) if not enabledTransitions.isEmpty():: microstep(enabledTransitions.toList()) # Here we invoke whatever needs to be invoked for state in statesToInvoke: for inv in state.invoke:invoke(inv)inv.invoke(inv) statesToInvoke.clear()previousConfiguration = configuration externalEvent = externalQueue.dequeue() # this call blocks until an event is available datamodel["event"] = externalEvent# Invoking may have raised internal error events and we # need to back up and handle those too if not internalQueue.isEmpty(): continue # A blocking wait for an external event externalEvent = externalQueue.dequeue() # Break if a "cancel.invoke.id" event turns up if externalEvent.name == "cancel.invoke." + datamodel["_sessionid"]: break datamodel["_event"] = externalEvent for state in configuration: for inv in state.invoke:if inv.invokeid == externalEvent.invokeid: # event is the result of an <invoke> in this stateif inv.invokeid == externalEvent.invokeid: applyFinalize(inv, externalEvent) if inv.autoforward:send(inv.id, externalEvent)send(inv.id, externalEvent) enabledTransitions = selectTransitions(externalEvent)if not enabledTransitions.isEmpty(): microstep(enabledTransitions.toList()) # now take any newly enabled null transitions and any transitions triggered by internal events macroStepComplete = false until macroStepComplete: enabledTransitions = selectEventlessTransitions() if enabledTransitions.isEmpty(): if internalQueue.isEmpty(): macroStepComplete = true else: internalEvent = internalQueue.dequeue() datamodel["event"] = internalEvent enabledTransitions = selectTransitions(internalEvent) if not enabledTransitions.isEmpty(): microstep(enabledTransitions.toList()) # if we get here, we have reached a top-level final state or some external entity has set continue to false exitInterpreter()if not enabledTransitions.isEmpty():: microstep(enabledTransitions.toList()) # If we get here, we have reached a top-level final state exitInterpreter()
procedure
exitInterpreter()
The purpose of this procedure is to exit the current SCXML process by exiting all active states. If the machine is in a top-level final state, a Done event is generated. (Note that in this case, the final state will be the only active state.) The implementation of returnDoneEvent is platform-dependent, but if this session is the result of an <invoke> in another SCXML session, returnDoneEvent will cause the event done.invoke.<id> to be placed in the external event queue of that session, where <id> is the id generated in that session when the <invoke> was executed.
procedure exitInterpreter(): statesToExit = configuration.toList().sort(exitOrder) for s in statesToExit: for content in s.onexit: executeContent(content) for inv in s.invoke: cancelInvoke(inv) configuration.delete(s) if isFinalState(s) and isScxmlState(s.parent): returnDoneEvent(s.donedata)
function
selectEventlessTransitions()
This
function
selects
all
transitions
that
are
enabled
in
the
current
configuration
that
do
not
require
an
event
trigger.
First
test
if
the
state
has
been
preempted
by
a
transition
that
has
already
been
selected
and
that
will
cause
the
state
to
be
exited
when
it
is
taken.
If
the
state
has
not
been
preempted,
find
a
transition
with
no
'event'
attribute
whose
condition
evaluates
to
true
.
If
multiple
matching
transitions
are
present,
take
the
first
in
document
order.
If
none
are
present,
search
in
the
state's
ancestors
in
ancestry
order
until
one
is
found.
As
soon
as
such
a
transition
is
found,
add
it
to
enabledTransitions,
and
proceed
to
the
next
atomic
state
in
the
configuration.
If
no
such
transition
is
found
in
the
state
or
its
ancestors,
proceed
to
the
next
state
in
the
configuration.
When
all
atomic
states
have
been
visited
and
transitions
selected,
return
filter
the
set
of
enabled
transitions.
transitions,
removing
any
that
are
preempted
by
other
transitions,
then
return
the
resulting
set.
function selectEventlessTransitions(): enabledTransitions = new OrderedSet() atomicStates = configuration.toList().filter(isAtomicState).sort(documentOrder) for state in atomicStates:if not isPreempted(state, enabledTransitions): loop: for s in [state].append(getProperAncestors(state, null)): for t in s.transition: if not t.event and conditionMatch(t): enabledTransitions.add(t) break looploop: for s in [state].append(getProperAncestors(state, null)): for t in s.transition: if not t.event and conditionMatch(t): enabledTransitions.add(t) break loop enabledTransitions = filterPreempted(enabledTransitions) return enabledTransitions
function
selectTransitions(event)
The purpose of the selectTransitions()procedure is to collect the transitions that are enabled by this event in the current configuration.
Create
an
empty
set
of
enabledTransitions
.
For
each
atomic
state
test
if
the
state
has
been
preempted
by
a
transition
that
has
already
been
selected
and
that
will
cause
the
state
to
be
exited
when
it
is
taken.
If
the
state
has
not
been
preempted,
,
find
a
transition
whose
'event'
attribute
matches
event
and
whose
condition
evaluates
to
true
.
If
multiple
matching
transitions
are
present,
take
the
first
in
document
order.
If
none
are
present,
search
in
the
state's
ancestors
in
ancestry
order
until
one
is
found.
As
soon
as
such
a
transition
is
found,
add
it
to
enabledTransitions,
and
proceed
to
the
next
atomic
state
in
the
configuration.
If
no
such
transition
is
found
in
the
state
or
its
ancestors,
proceed
to
the
next
state
in
the
configuration.
When
all
atomic
states
have
been
visited
and
transitions
selected,
filter
out
any
preempted
transitions
and
return
the
set
of
enabled
transitions.
resulting
set.
function selectTransitions(event): enabledTransitions = new OrderedSet() atomicStates = configuration.toList().filter(isAtomicState).sort(documentOrder) for state in atomicStates:if not isPreempted(state, enabledTransitions): loop: for s in [state].append(getProperAncestors(state, null)): for t in s.transition: if t.event and nameMatch(t.event, event.name) and conditionMatch(t): enabledTransitions.add(t) break looploop: for s in [state].append(getProperAncestors(state, null)): for t in s.transition: if t.event and nameMatch(t.event, event.name) and conditionMatch(t): enabledTransitions.add(t) break loop enabledTransitions = filterPreempted(enabledTransitions) return enabledTransitions
function
Return
true
if
Filter
out
any
transition
in
enabledTransitions
that
is
preempted
by
a
transition
T
that
precedes
it
in
transitionList
exits
an
ancestor
of
enabledTransitions.
Note
that
enabledTransitions
will
contain
multiple
transitions
only
if
a
parallel
state
s.
is
active.
In
this
that
case,
taking
T
will
pull
the
state
machine
out
we
may
have
one
transition
selected
for
each
of
s
and
thus
its
children.
These
transitions
may
conflict
with
each
other
in
the
sense
that
they
have
incompatible
target
states.
When
such
a
conflict
occurs,
we
select
the
first
transition
in
document
order
and
say
that
it
preempts
the
selection
other
transitions.
function filterPreempted(enabledTransitions): filteredTransitions = new OrderedSet() for t in enabledTransitions: # does any t2 in filteredTransitions preempt t? if not, add t to filteredTransitions if not filteredTransitions.some(lambda t2: preemptsTransition(t2, t)): filteredTransitions.add(t) return filteredTransitions
function
preemptsTransition(t1,
t2)
function isPreempted(s, transitionList): preempted = false for t in transitionList: if t.target: LCA = findLCA([t.source].append(getTargetStates(t.target))) if isDescendant(s,LCA): preempted = true break return preemptedfunction preemptsTransition(t1, t2): if isType2(t) and isType3(t2): return True elif isType3(t): return True else return False
procedure
microstep(enabledTransitions)
The
purpose
of
the
microstep
procedure
is
to
process
a
single
set
of
transitions.
These
may
have
been
enabled
by
an
external
event,
an
internal
event,
or
by
the
presence
or
absence
of
certain
values
in
the
datamodel
at
the
current
point
in
time.
The
processing
of
the
enabled
transitions
must
be
done
in
parallel
('lock
step')
in
the
sense
that
their
source
states
must
first
be
exited,
then
their
actions
must
be
executed,
and
finally
their
target
states
entered.
If a single atomic state is active, then enabledTransitions will contain only a single transition. If multiple states are active (i.e., we are in a parallel region), then there may be multiple transitions, one per active atomic state (though some states may not select a transition.) In this case, the transitions are taken in the document order of the atomic states that selected them.
procedure microstep(enabledTransitions): exitStates(enabledTransitions) executeTransitionContent(enabledTransitions) enterStates(enabledTransitions)
procedure
exitStates(enabledTransitions)
Create
an
empty
statesToExit
set.
For
each
transition
t
in
enabledTransitions,
if
t
is
targetless
then
do
nothing,
else
then
let
LCA
the
transition's
ancestor
state
be
the
source
state
(in
the
case
of
internal
transitions)
or
(in
the
case
of
external
transitions)
the
least
common
compound
ancestor
state
of
the
source
state
and
target
states
of
t.
Add
to
the
statesToExit
set
all
states
in
the
configuration
that
are
descendants
of
LCA.
the
ancestor.
Next
remove
all
the
states
on
statesToExit
from
the
set
of
states
that
will
have
invoke
processing
done
at
the
start
of
the
next
macrostep.
(Suppose
macrostep
M1
consists
of
microsteps
m11
and
m12.
We
may
enter
state
s
in
m11
and
exit
it
in
m12.
We
will
add
s
to
statesToInvoke
in
m11,
and
must
remove
it
in
m12.
In
the
subsequent
macrostep
M2,
we
will
apply
invoke
processing
to
all
states
that
were
enter,
entered,
and
not
exited,
in
M1.)
Then
convert
statesToExit
to
a
list
and
sort
it
in
exitOrder.
For each state s in the list, if s has a deep history state h, set the history value of h to be the list of all atomic descendants of s that are members in the current configuration, else set its value to be the list of all immediate children of s that are members of the current configuration. Again for each state s in the list, first execute any onexit handlers, then cancel any ongoing invocations, and finally remove s from the current configuration.
procedure exitStates(enabledTransitions): statesToExit = new OrderedSet() for t in enabledTransitions: if t.target:if t.type == "internal" and getTargetStates(t.target).every(lambda s: isDescendant(s,t.source)):tstates = getTargetStates(t.target) if t.type == "internal" and isCompoundState(t.source) and tstates.every(lambda s: isDescendant(s,t.source)):: ancestor = t.source else:ancestor = findLCA([t.source].append(getTargetStates(t.target)))ancestor = findLCCA([t.source].append(getTargetStates(t.target))) for s in configuration: if isDescendant(s,ancestor): statesToExit.add(s) for s in statesToExit: statesToInvoke.delete(s) statesToExit = statesToExit.toList().sort(exitOrder) for s in statesToExit: for h in s.history: if h.type == "deep": f = lambda s0: isAtomicState(s0) and isDescendant(s0,s) else: f = lambda s0: s0.parent == s historyValue[h.id] = configuration.toList().filter(f) for s in statesToExit: for content in s.onexit: executeContent(content) for inv in s.invoke: cancelInvoke(inv) configuration.delete(s)
procedure
executeTransitionContent(enabledTransitions)
For
each
transition
in
the
list
of
enabledTransitions
,
execute
its
executable
content.
procedure executeTransitionContent(enabledTransitions): for t in enabledTransitions: executeContent(t)
procedure
enterStates(enabledTransitions)
Create
an
empty
statesToEnter
set,
and
an
empty
statesForDefaultEntry
set.
For
each
transition
t
in
enabledTransitions,
if
t
is
targetless
then
do
nothing,
else
for
each
target
state
s,
call
addStatesToEnter.
This
will
add
to
statesToEnter
s
plus
any
descendent
descendant
states
that
will
have
to
be
entered
by
default
once
s
is
entered.
(If
s
is
atomic,
there
will
not
be
any
such
states.)
Now
for
each
target
state
s,
add
any
of
s's
ancestors
that
must
be
entered
when
s
is
entered.
(These
will
be
any
ancestors
of
s
that
are
not
currently
active.
Note
that
statesToEnter
is
a
set,
so
it
is
harmless
if
the
same
ancestor
is
entered
multiple
times.)
In
the
case
where
the
ancestor
state
is
parallel,
call
addStatesToEnter
on
any
of
its
child
states
that
do
not
already
have
a
descendent
descendant
on
statesToEnter.
(If
a
child
state
already
has
a
descendant
on
statesToEnter,
it
will
get
added
to
the
list
when
we
examine
the
ancestors
of
that
descendant.)
We
now
have
a
complete
list
of
all
the
states
that
will
be
entered
as
a
result
of
taking
the
transitions
in
enabledTransitions.
Add
them
to
statesToInvoke
so
that
invoke
processing
can
be
done
at
the
start
of
the
next
macrostep.
Convert
statesToEnter
to
a
list
and
sort
it
in
entryorder.
entryOrder.
For
each
state
s
in
the
list,
first
add
s
to
the
current
configuration.
Then
if
we
are
using
late
binding,
and
this
is
the
first
time
we
have
entered
s,
initialize
its
data
model.
Then
execute
any
onentry
handlers.
If
s's
initial
state
is
being
entered
by
default,
execute
any
executable
content
in
the
initial
transition.
Finally,
if
s
is
a
final
state,
generate
relevant
Done
events.
If
we
have
reached
a
top-level
final
state,
set
continue
running
to
false
as
a
signal
to
stop
processing.
procedure enterStates(enabledTransitions): statesToEnter = new OrderedSet() statesForDefaultEntry = new OrderedSet() for t in enabledTransitions: if t.target: tstates = getTargetStates(t.target)if t.type == "internal" and tstates.every(lambda s: isDescendant(s,t.source)):if t.type == "internal" and isCompoundState(t.source) and tstates.every(lambda s: isDescendant(s,t.source)): ancestor = t.source else:ancestor = findLCA([t.source].append(tstates))ancestor = findLCCA([t.source].append(tstates)) for s in tstates: addStatesToEnter(s,statesToEnter,statesForDefaultEntry) for s in tstates: for anc in getProperAncestors(s,ancestor): statesToEnter.add(anc) if isParallelState(anc): for child in getChildStates(anc): if not statesToEnter.some(lambda s: isDescendant(s,child)): addStatesToEnter(child,statesToEnter,statesForDefaultEntry)for s in statesToEnter: statesToInvoke.add(s)statesToEnter = statesToEnter.toList().sort(enterOrder) for s in statesToEnter: configuration.add(s) statesToInvoke.add(s) if binding == "late" and s.isFirstEntry: initializeDataModel(datamodel.s,doc.s) s.isFirstEntry = false for content in s.onentry: executeContent(content) if statesForDefaultEntry.member(s): executeContent(s.initial.transition) if isFinalState(s): parent = s.parent grandparent = parent.parentinternalQueue.enqueue(new Event("done.state." + parent.id, parent.donedata))internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata)) if isParallelState(grandparent): if getChildStates(grandparent).every(isInFinalState):internalQueue.enqueue(new Event("done.state." + grandparent.id, grandparent.donedata))internalQueue.enqueue(new Event("done.state." + grandparent.id)) for s in configuration: if isFinalState(s) and isScxmlState(s.parent):continue = falserunning = false
procedure
addStatesToEnter(state,root,statesToEnter,statesForDefaultEntry)
The purpose of this procedure is to add to statesToEnter state and/or any of its descendants that must be entered as a result of state being the target of a transition. Note that this procedure permanently modifies both statesToEnter and statesForDefaultEntry.
First,
If
state
is
a
history
state
then
add
either
the
history
values
associated
with
state
or
state's
default
target
to
statesToEnter.
Else
(if
state
is
not
a
history
state),
add
state
to
statesToEnter.
Then,
if
state
is
a
a
compound
state,
add
state
to
statesForDefaultEntry
and
recursively
call
addStatesToenter
addStatesToEnter
on
its
default
initial
state(s).
Otherwise,
if
state
is
a
parallel
state,
recursively
call
addStatesToEnter
on
each
of
its
child
states.
procedure addStatesToEnter(state,statesToEnter,statesForDefaultEntry): if isHistoryState(state): if historyValue[state.id]: for s in historyValue[state.id]: addStatesToEnter(s,statesToEnter,statesForDefaultEntry) for anc in getProperAncestors(s,state): statesToEnter.add(anc) else: for t in state.transition: for s in getTargetStates(t.target): addStatesToEnter(s,statesToEnter,statesForDefaultEntry) else: statesToEnter.add(state) if isCompoundState(state): statesForDefaultEntry.add(state) for s in getTargetStates(state.initial): addStatesToEnter(s,statesToEnter,statesForDefaultEntry) elif isParallelState(state): for s in getChildStates(state): addStatesToEnter(s,statesToEnter,statesForDefaultEntry)
procedure
isInFinalState(s)
Return true if s is a compound <state> and one of its children is an active <final> state (i.e. is a member of the current configuration), or if s is a <parallel> state and isInFinalState is true of all its children.
function isInFinalState(s): if isCompoundState(s): return getChildStates(s).some(lambda s: isFinalState(s) and configuration.member(s)) elif isParallelState(s): return getChildStates(s).every(isInFinalState) else: return false
function
The
Least
Common
Compound
Ancestor
is
the
<state>
or
<scxml>
element
s
such
that
s
is
a
proper
ancestor
of
all
states
on
stateList
and
no
descendant
of
s
has
this
property.
Note
that
there
is
guaranteed
to
be
such
an
element
since
the
<scxml>
wrapper
element
is
a
common
ancestor
of
all
states.
Note
also
that
since
we
are
speaking
of
proper
ancestor
(parent
or
parent
of
a
parent,
etc.)
the
LCA
LCCA
is
never
a
member
of
stateList.
function findLCA(stateList): for anc in getProperAncestors(stateList.head(), null):function findLCCA(stateList): for anc in getProperAncestors(stateList.head(),null).filter(isCompoundState): if stateList.tail().every(lambda s: isDescendant(s,anc)): return anc
function
getProperAncestors(state1,
state2)
If state2 is null, returns the set of all ancestors of state1 in ancestry order (state1's parent followed by the parent's parent, etc.). If state2 is non-null, returns in ancestry order the set of all ancestors of state1, up to but not including state2.
The schemas for SCXML can be found in www.w3.org/2011/04/SCXML . The master schema is http://www.w3.org/2011/04/SCXML/scxml.xsd . The schema for SCXML messages is http://www.w3.org/2011/04/SCXML/scxml-message.xsd
This
[This
section
is
normative.
normative.]
The following conformance requirements hold for all SCXML documents.
A SCXML 1.0 processor is a user agent that can parse and process Conforming SCXML 1.0 documents.
In a Conforming SCXML 1.0 Processor, the XML parser MUST be able to parse and process all well-formed XML constructs defined within [XML] and [XMLNames] . It is not required that a Conforming SCXML 1.0 processor use a validating parser.
A Conforming SCXML 1.0 Processor MUST support the syntax and semantics of all mandatory SCXML elements described in this document. A Conforming SCXML 1.0 Processor MAY support the syntax and semantics of any optional SCXML elements described in this document. A Conforming SCXML 1.0 Processor MUST behave as if it were executing the algorithm specified in A Algorithm for SCXML Interpretation .
When a Conforming SCXML 1.0 Processor encounters a Conforming SCXML 1.0 Document with non-SCXML elements or attributes which are proprietary, or defined in a non-SCXML namespace, it MUST behave as instructed by the 'exmode' attribute.
When a Conforming SCXML 1.0 Processor encounters a nonconformant document, then if 'exmode' is "strict", it MUST reject the document and SHOULD signal an error to the entity that requested the execution of the document. The means of signaling this error are platform-specific and outside the scope of this specification. Note specifically that in this case, a Conforming SCXML Processor MUST NOT enter the initial state of a nonconformant SCXML document. When a Conforming SCXML 1.0 Processor encounters a nonconformant document, and 'exmode' is not "strict", its behavior is undefined.
There is no conformance requirement with respect to performance characteristics of the SCXML 1.0 Processor.
[This section is normative.]
The
'datamodel'
attribute
on
<scxml>
defines
the
data
model
that
the
document
uses.
The
data
model
includes
the
underlying
data
structure
plus
languages
for
boolean
expressions,
location
expressions,
value
expressions,
and
scripting.
Each
A
conformant
SCXML
document
MUST
MAY
specify
the
data
model
it
uses.
(Note
that
the
The
"null"
data
model
is
the
default.)
default.
Conformant
SCXML
processors
MUST
support
the
null
data
model,
and
MAY
support
other
data
models,
including
the
ECMAScript
and
XPath
data
models.
The
ECMAScript
and
XPath
model
definitions
given
here
are
normative
in
the
sense
that
they
define
how
implementations
that
support
one
of
these
languages
MUST
behave.
The
intent
is
to
insure
ensure
interoperability
among
all
processors
that
support
ECMAScript,
and
all
those
that
support
XPath,
without
requiring
all
implementations
to
support
either
of
those
data
model
languages.
The definition of a data model MUST :
The value "null" for the 'datamodel' attribute results in an absent or empty data model. In particular:
The boolean expression language consists of the In predicate only . It has the form 'In( id )', where id is the id of a state in the enclosing state machine. The predicate MUST return 'true' if and only if that state is in the current state configuration.
The <foreach> element and the elements defined in 5 Data Model and Data Manipulation are not supported in the Null Data Model. If the SCXML processor encounters a document specifying the Null Data Model and containing one of these elements, it MUST behave as instructed by the 'exmode' attribute on <scxml>. See 3.2 <scxml> for details.
The value 'ecmascript' for the 'datamodel' attribute results in an ECMASccript data model. Implementations that support this value MUST support the third edition of ECMAScript [ECMASCRIPT-262] . Implementations MAY support ECMAScript for XML (E4X) [E4X] .
For
each
<data>
element
in
the
document,
the
SCXML
Processor
MUST
create
an
ECMAScript
variable
object
whose
name
is
the
value
of
the
"id"
attribute
of
<data>
.
Note
that
the
value
of
the
variable
can
be
assigned
in
one
of
the
following
three
ways:
If no value is assigned, the SCXML Processor MUST assign the variable the default value ECMAScript undefined. Note that the assignment takes place at the time indicated by the 'binding' attribute on the <scxml> element.
The Processor MAY support evaluation of JSON expressions and of XML expressions.
<scxml version="1.0" datamodel="ecmascript"> <datamodel> <data id="employees" src="http://example.com/employees.json"/> <data id="year" expr="2008"/> <data id="CEO" expr="\"Mr Big\""/> <data id="profitable" expr="true"/> </datamodel> </scxml>
The Processor MUST place all variables in a single global ECMAScript scope.
The Processor MUST convert ECMAScript expressions used in conditional expressions into their effective boolean value using the ToBoolean operator as described in Section 9.2 of [ECMASCRIPT-262] .
The following example illustrates this usage.
<state id="errorSwitch"> <datamodel> <data id="time"/> </datamodel> <onentry> <assign location="time" expr="currentDateTime()"/> </onentry> <transition cond="yearFromDatetime(time) > 2009" target="newBehavior"/> <transition target="currentBehavior"/> </state>
The
SCXML
processor
MUST
add
define
an
ECMAScript
function
to
the
SCXML
namespace
named
'In()'
that
takes
a
stateID
as
its
argument
and
returns
'true'
if
and
only
if
that
state
is
in
the
current
state
configuration,
as
described
in
5.10.1
Conditional
Expressions
.
Here
is
an
example
of
its
use,
taken
from
G.3
Microwave
Example
(Using
parallel)
below:
<transition cond="In('closed')" target="cooking"/>
The
SCXML
Processor
MUST
accept
any
ECMAScript
left-hand-side
expression
as
a
location
expression.
The
following
example
illustrates
this
usage.
(Note
that
the
example
assumes
that
the
data
loaded
from
http://http://example.com/employees.json
http://example.com/employees.json
creates
the
necessary
data
structure,
so
that
employees.employee[12].salary
exists
when
<assign>
is
evaluated.
If
it
didn't,
the
Processor
would
raise
error.execution
and
the
<assign>
would
have
no
effect.)
The SCXML Processor MUST accept any ECMAScript expression as a value expression.
When
evaluating
an
<assign>
element
in
the
ECMA
ECMAScript
data
model,
the
SCXML
Processor
MUST
replace
the
existing
value
at
'location'
with
the
value
produced
by
evaluating
'expr'.
If
it
is
unable
to
do
so
(for
example,
if
'location'
evaluates
to
ECMAScript
'null'
or
'undefined'),
it
MUST
place
the
error
error.execution
on
the
internal
event
queue.
The
SCXML
Processor
MUST
define
an
ECMAScript
read-only
variable
for
each
system
variable
defined
in
5.11
System
Variables
.
The
_sessionid
and
_name
system
variables
are
defined
as
variables
with
ECMAScript
String
values.
The
_event
system
variable
is
defined
as
an
object
with
properties
for
each
of
the
fields
defined
in
5.11.1
The
Internal
Structure
of
Events
:
name
,
type
,
sendid
,
origin
,
origintype
,
and
invokeid
are
String
values,
while
data
is
an
Object
value.
Suppose as part of executing a state machine named "myName" with a platform-assigned sessionid "12345", we are processing an event with the name "foo.bar" and the following object payload:
{ "answer" : 42 }
Then
the
underlying
ECMA
ECMAScript
datamodel
would
have
the
following
form:
{// The three properties below are automatically populated by the system// The four properties below are automatically populated by the system "_name" : "myName" , "_sessionid" : "12345" , "_event" : { "name" : "foo.bar" , "data" : { "answer" : 42 } } , "_ioprocessors" : { "http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor" : { "location" : "http://example.com/scxml-http/12345" } "http://www.w3.org/TR/scxml/#SCXMLEventProcessor" : { "location" : "http://example.com/scxml-http/12345" } } , // Rest of the application / developer-authored data model goes here }
As
an
example,
here
is
a
sample
transition
that
accesses
the
_event
variable
in
that
data
model.
The SCXML Processor MUST accept any ECMAScript program as defined in Section 14 of [ECMASCRIPT-262] as the content of a <script> element.
In
the
ECMA
ECMAScript
data
model,
the
'array'
value
expression
SHOULD
evaluate
to
an
ECMAScript
array
(i.e.
the
result
of
the
expression
SHOULD
legal
iterable
collections
are
arrays,
namely
objects
that
satisfy
instanceof(Array)
in
ECMAScript).
ECMAScript.
The
legal
values
for
the
'item'
attribute
SHOULD
specify
a
are
legal
ECMAScript
variable
name.
names.
The
iteration
order
is
the
order
of
the
underlying
ECMAScript
array,
and
goes
from
an
index
of
0
by
increments
of
one
to
an
index
of
array_name.length
-
1.
Note
that
since
shallow
copy
is
required
<foreach>
assignment
is
equivalent
to
item
=
array_name[index]
in
ECMAScript.
Note
also
that
the
assigned
value
could
be
undefined
for
a
sparse
array.
5.5
<validate>
is
not
supported
in
the
ECMA
ECMAScript
Data
Model.
If
the
SCXML
processor
encounters
a
document
specifying
the
ECMA
ECMAScript
Data
Model
and
containing
this
element,
it
MUST
behave
as
instructed
by
the
'exmode'
attribute
on
<scxml>.
See
3.2
<scxml>
for
details.
The value "xpath" for the 'datamodel' attribute results in an XML data model with XPath used as the expression language. Implementations that support this data model MUST support [XPath 2.0] .
For each <data> element in the document, the SCXML Processor MUST create an XPath variable whose name is the value of the 'id' attribute of the element. Note that the value of the variable can be assigned in one of the following three ways:
If no value is assigned, the SCXML Processor MUST assign the variable the default value as the following DOM node:
<data xmlns=""></data>
Note that the assignment takes place at the time indicated by the 'binding' attribute on the <scxml> element.
The Processor MUST place all variables in a single global XPath scope, such that they are subsequently available to all expressions within the document.
<scxml version="1.0" datamodel="xpath"> <datamodel> <data id="company"> <about xmlns=""> <name>Example company</name> <website>example.com</website> <CEO>John Doe</CEO> </about> </data> <data id="employees" src="http://example.com/employees.xml"/> <data id="defaultdata"/> </datamodel> </scxml>
The SCXML Processor MUST accept any XPath 2.0 expression as a conditional expression and MUST convert it into its effective boolean value as described in section 2.4.3 of the [XPath 2.0] specification. The following example illustrates this usage.
<state id="errorSwitch" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <datamodel> <data id="time"/> </datamodel> <onentry> <assign location="$time" expr="fn:current-dateTime()"/> </onentry> <transition cond="fn:year-from-dateTime($time) > 2009" target="newBehavior"/> <transition target="currentBehavior"/> </state>
The
SCXML
processor
MUST
add
define
an
XPath
function
to
the
SCXML
namespace
'In()'
that
takes
a
stateID
as
its
argument
and
returns
'true'
if
and
only
if
that
state
is
in
the
current
state
configuration,
as
described
in
5.10.1
Conditional
Expressions
.
For
examples
of
the
use
of
this
predicate
(but
in
an
ECMAScript
context),
see
G.3
Microwave
Example
(Using
parallel)
.
Function
signature:
In($stateID
as
xs:string?)
as
xs:boolean
Returns
an
xs:boolean
indicating
whether
or
not
the
state
with
ID
$stateID
is
one
of
the
currently
active
states.
The SCXML Processor MUST accept any XPath 2.0 expression as a location expression. The following example illustrates this usage:
<state id="errorSwitch"> <datamodel> <data id="cities"> <list xmlns=""> <city id="nyc" count="0">New York</city> <city id="bos" count="0">Boston</city> </list> </data> </datamodel> <onentry> <assign location="$cities/list/city[@id='nyc']/@count" expr="1"/> </onentry> </state>
The SCXML Processor MUST allow any XPath expression to be used as a value expression. If the result of the value expression is a node-set, the Processor MUST make a deep copy of the subtree rooted at each node.
Implementations
supporting
the
XPath
datamdel
datamodel
MUST
support
the
following
additional
attributes
for
the
<assign>
element.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
type | false | enum | replacechildren | replacechildren, firstchild, lastchild, previoussibling, nextsibling, replace, delete, addattribute | Defines the nature of the insertion to be performed. See below for details. | |
attr | false | This attribute must be present if and only if 'type' is 'addattribute'. | NMTOKEN | none | The attribute name to add at the specified location. |
The SCXML Processor MUST modify the datamodel as directed by the 'type' attribute as described below. If it is unable to do so, it MUST place the error error.execution on the internal event queue:
Note that in the case of an XML data model, it is not required to assign to the root of a tree (i.e., the "name" value in a <data> tag), since the path expression can reach down into the tree to assign a new value to an internal node. The following examples show various aspects of assignment in the XPath data model. Suppose we have a data model of the following form:
<data id="cart"> <myCart xmlns=""> <books> <book> <title>The Zen Mind</title> </book> <book> <title>Freakonomics</title> </book> </books> <cds> <cd name="Something"/> </cds> </myCart> </data>
Here is an example of assignment of a string to an element node.
<assign location="$cart/myCart/books/book[1]/title" expr="'My favorite book'"/>
results in
<data id="cart"> <myCart xmlns=""> <books> <book> <title>My favorite book</title> </book> <book> <title>Freakonomics</title> </book> ... </data>
Now suppose we assign an xml structure to an element node. The following assignment statement would have the effect of replacing the children of the element "$cart/myCart/books/book[1]" by the XML tree rooted in <bookinfo>.
<assign location="$cart/myCart/books/book[0]"> <bookinfo xmlns=""> <isdn>12334455</isdn> <author>some author</author> </bookinfo> </assign>
results in
<data id="cart"> <myCart xmlns=""> <books> <book> <bookinfo> <isdn>12334455</isdn> <author>some author</author> </bookinfo> </book> <book> <title>Freakonomics</title> </book> ... </data>
Here are examples of legal and illegal assignment to an attribute:
<!-- Legal assignment: --> <assign location="$cart/myCart/cds/cd/@name" expr"'Something Else'"/> <!-- Illegal assignment: --> <assign location="$cart/myCart/cds/cd/@name" > <foo> <bar/> </foo> </assign>
Now suppose we assign a string to a nodeset. The following assignment statement would have the effect of replacing the children of each node in the nodeset $cart/myCart/books/book with the string "The Zen Mind":
<assign location="$cart/myCart/books/book" expr="'The Zen Mind'"/>
results in
<data id="cart"> <myCart xmlns=""> <books> <book>The Zen Mind</book> <book>The Zen Mind</book> </books> ... </data>
Finally suppose we assign a structure to a nodeset. The following statement would iterate over the elements in the nodeset of <book> elements and replace their children with the <price> structure:
<assign location="$cart/myCart/books/book"> <price>20.0</price> </assign>
results in
<data id="cart"> <myCart xmlns=""> <books> <book> <price>20.0</price> </book> <book> <price>20.0</price> </book> </books> ... </data>
If the evaluation of any of the expressions in an <assign> element causes an error to be raised, evaluation of the element terminates immediately and the <assign> has no effect. For example, the following assignment statement would raise an error because the sample datamodel we are using does not have an <ISBN> node as a child of <book>:
<assign location="$cart/myCart/books/book[1]/ISBN" expr="'....'"/>
The SCXML Processor MUST create an implicit <data> element for each system variable defined in 5.11 System Variables .
Suppose as part of executing a state machine named "myName" with a platform-assigned sessionid "12345", we are processing an event with the name "foo.bar" and the following XML payload:
<payload xmlns=""> <answer>42</answer> </payload>
Then the underlying XML datamodel would have the following form:
<datamodel><!-- The three data elements below are automatically populated by the system --><!-- The four data elements below are automatically populated by the system --> <data id="_name">myName</data> <data id="_sessionid">12345</data> <data id="_event"> <name xmlns="">foo.bar</name> <data xmlns=""> <payload> <answer>42</answer> </payload> </data> </data> <data id="_ioprocessors"> <basichttp xmlns=""> <location>http://example.com/scxml-http/12345</location> </basichttp> <scxml xmlns=""> <location/> </scxml> </data> <!-- Rest of the application / developer-authored data model goes here --> </datamodel>
As
an
example,
here
is
a
sample
transition
that
accesses
the
$_sessionid
variable
in
that
data
model.
<state id="checkSessionid"> <transition cond="$_sessionid = '12345'" target="nextState"/> ... </state>
In
the
XPath
data
model,
the
'array'
value
expression
SHOULD
evaluate
to
an
Node-set
legal
iterable
collections
are
Node-Sets.
The
legal
values
for
the
'item'
attribute
SHOULD
specify
a
are
legal
XPath
variable
name.
names.
The
iteration
order
is
the
order
of
the
underlying
Node-set,
and
goes
from
an
index
of
1
by
increments
of
one
to
an
index
of
count(node-set).
5.9 <script> is not supported in the XPath Data Model. If the SCXML processor encounters a document specifying the XPath Data Model and containing this element, it MUST behave as instructed by the 'exmode' attribute on <scxml>. See 3.2 <scxml> for details.
[This section is normative.]
The SCXML Event I/O Processor is intended to transport messages in a specific format to and from SCXML sessions. This processor specifies the schema of the message and how it maps onto SCXML events, but it does not define the transport mechanism, which is platform-specific. The schema for the message is available at http://www.w3.org/2011/04/SCXML/scxml-message.xsd . SCXML Processors MUST support sending messages to and receiving messages from other SCXML sessions using the SCXML Event I/O Processor. An SCXML Processor MAY support exchanging messages with non-SCXML endpoints using the SCXML Event I/O Processor. However this specification defines the behavior for SCXML endpoints only.
The contents of the message are defined as follows:
Here is a summary of the mapping between <send>, the SCXML message structure, and the event that is raised in the receiving session.
<send> element | SCXML Message Structure | Target Session Event |
---|---|---|
'event' attribute | 'name' attribute | 'name' field |
not present in <send> but known to platform | 'source' attribute | 'origin' field |
'target' attribute | 'target' attribute | not present |
literal provided by author or value generated by platform | 'sendid' attribute | 'sendid' field |
not present | 'sourcetype' attribute. Always "scxml". | 'origintype' field. Always "scxml". |
|
<payload> element | data field |
When
an
SCXML
Processor
receives
a
message
via
the
SCXML
Event
I/O
Processor
it
MUST
validate
the
syntax
of
the
incoming
message
and
check
that
it
matches
an
active
session.
If
the
message
fails
syntactic
validation
or
does
not
match
an
active
session,
the
Processor
MUST
notify
the
sending
processor
of
the
error
and
MUST
ignore
the
message.
If
the
message
passes
validation,
but
the
receiving
Processor
cannot
handle
the
data
format
contained
in
the
message,
the
receiving
Processor
MUST
place
the
error
error.communication
in
internal
queue
of
the
session
for
which
the
message
was
intended
and
MUST
ignore
the
message.
The
Processor
SHOULD
also
notify
the
sending
endpoint
of
the
error.
If
no
errors
occur,
the
receiving
Processor
CONVERT
MUST
convert
the
message
into
an
SCXML
event,
using
the
mapping
defined
above,
and
CONVERT
MUST
insert
the
event
its
external
event
queue.
If the sending entity is an SCXML session, it SHOULD also report errors. For example, if the sending session specifies a sessionid that does not exist on the receiving system, specifies a data format that the receiving session does not support, or is unable to connect to the receiving system, it SHOULD place the error error.communication on the internal event queue.
If the current session was triggered by an instance of <invoke>, the SCXML Event I/O Processor MUST handle the 'cancel.invoke. id ' event as defined in 6.4.3 Implementation of <invoke> . In other cases (namely if the current session was not triggered by an instance of <invoke> or if the id does not match the invokeid of the triggering <invoke> element), the SCXML Event I/O processor MUST discard the event and SHOULD signal an error.
The SCXML Processor MUST maintain a 'location' field inside the entry for the SCXML Event I/O Processor in the _ioprocessors system variable. Its value MUST hold an address that external entities can use to communicate with this SCXML session using the SCXML Event I/O Processor.
Here are some examples of SCXML messages sent between SCXML sessions. Each example shows the original <send> element, the corresponding <message> structures and a transition handling the resulting event in the receiving SCXML session.
EXAMPLE 1: First, here is a message with an XML payload generated by <send> with a 'namelist':
SESSION1 : SENDING SESSION Pattern: "event" attribute with an optional "namelist" <datamodel> <data id="email" expr="'mailto:recipient@example.com'"/> <data id="content" expr="'http://www.example.com/mycontent.txt'"/> <data id="xmlcontent"> <headers xmlns="http://www.example.com/headers"> <cc>archive@example.com</cc> <subject>Example email</subject> </headers> </data> </datamodel> ... <send id="send-123" target="http://scxml-processors.example.com/session2" type="scxml" event="email.send" namelist="email content xmlcontent"/>
Here is the actual XML message that will be sent over platform-specific transport and converted into an event in the target SCXML session:
<scxml:message xmlns:scxml="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/07/scxml scxml-message.xsd" source="http://scxml-processors.example.com/session1" sourcetype="scxml"target="http://scxml-processors.example.com/session2" type="scxml"target="http://scxml-processors.example.com/session2" sendid="send-123" name="email.send"> <scxml:payload> <scxml:property name="email">mailto:recipient@example.com</scxml:property> <scxml:property name="content">http://www.example.com/mycontent.txt</scxml:property> <scxml:property name="xmlcontent"> <headers xmlns="http://www.example.com/headers"> <cc>archive@example.com</cc> <subject>Example email</subject> </headers> </scxml:property> <scxml:hint>Email headers</scxml:hint> </scxml:payload> </scxml:message>
Here is sample SCXML code to process that event in the receiving SCXML session. In this example <my:email> is platform-specific executable content that sends an email:
SESSION2 : RECEIVING SESSION Pattern: "event" attribute with an optional "namelist" <scxml:transition event="email.send"> <my:email to="data('_event')/scxml:property[@name='email']" cc="data('_event')/scxml:property[@name='xmlcontent']/h:headers/h:cc" subject="data('_event')/scxml:property[@name='xmlcontent']/h:headers/h:subject" content="data('_event')/scxml:property[@name='content']"/> </scxml:transition>
EXAMPLE 2: The next example shows <send> using inline XML content:
SESSION1 : SENDING SESSION Pattern: "xmlns" attribute with explicit inline content <send id="send-123" target="http://scxml-processors.example.com/session2" type="scxml" xmlns:csta="http://www.ecma.ch/standards/ecma-323/csta"> <content> <csta:MakeCall> <csta:callingDevice>22343</callingDevice> <csta:calledDirectoryNumber>18005551212</csta:calledDirectoryNumber> </csta:MakeCall> </content> </send>
Here is the actual XML message that will be sent:
<scxml:message xmlns:scxml="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/07/scxml scxml-message.xsd" source="http://scxml-processors.example.com/session1" target="http://scxml-processors.example.com/session2" sendid="send-123"> <scxml:payload xmlns:csta="http://www.ecma.ch/standards/ecma-323/csta"> <csta:MakeCall> <csta:callingDevice>22343</csta:callingDevice> <csta:calledDirectoryNumber>18005551212</csta:calledDirectoryNumber> </csta:MakeCall> </scxml:payload> </scxml:message>
Here is sample SCXML code to process the resulting event in the receiving SCXML session. It uses the special executable content <csta:makecall> to generate a telephone call:
SESSION2 : RECEIVING SESSION Pattern: "xmlns" attribute with explicit inline content <scxml:transition event="external.event"> <csta:makecall callingDevice="data('_event')/csta:MakeCall/csta:callingDevice" callingDirectoryNumber="data('_event')/csta:MakeCall/csta:callingDirectoryNumber"/> </scxml:transition>
EXAMPLE 3: Finally, here is an example generated by <send> using both 'event' and 'namelist' attributes and using JSON content:
SESSION1 : SENDING SESSION Pattern: "event" attribute with an optional "namelist" <datamodel> <data id="email" expr="'mailto:recipient@example.com'"/> <data id="content" expr="'http://www.example.com/mycontent.txt'"/> <data id="jsoncontent" src="http://www.example.com/headers.json"/> </datamodel> ... <send sendid="send-123" target="'http://scxml-processors.example.com/session2'" type="'scxml'" event="'email.send'" namelist="email content jsoncontent"/>
Here is the actual XML message that will be sent over platform-specific transport and converted into an event in the target SCXML session:
<scxml:message xmlns:scxml="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/07/scxml scxml-message.xsd" source="http://scxml-processors.example.com/session1" target="http://scxml-processors.example.com/session2" sendid="send-123" name="email.send" language="json"> <scxml:payload> <scxml:property name="email">mailto:recipient@example.com</scxml:property> <scxml:property name="content">http://www.example.com/mycontent.txt</scxml:property> <scxml:property name="jsoncontent"> <![CDATA[ headers : { cc : "audit@example.com" , subject : "Example email" } ]]> </scxml:property> <scxml:hint>Email headers</scxml:hint> </scxml:payload> </scxml:message>
Here is sample SCXML code to process the resulting event in the receiving SCXML session. In this example, <my:email> is special executable content as in the first example.
SESSION2 : RECEIVING SESSION Pattern: "event" attribute with an optional "namelist" <scxml:transition event="email.send"> <my:email to="_event.email" cc="_event.jsoncontent.headers.cc" subject="_event.jsoncontent.headers.subject" content="_event.content"/> </scxml:transition>
In some cases it may be convenient to included multiple <message> structures in a single payload. The following schema defines a <messages> element which contains multiple <message> elements. Support for this schema is optional.
scxml-messages.xsd
<?xml version="1.0" encoding="UTF-8"?> <!-- XML Schema for sending messages to SCXML processors. --> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3.org/2005/07/scxml" xmlns="http://www.w3.org/2005/07/scxml" elementFormDefault="qualified"> <xsd:include schemaLocation="scxml-message.xsd"/> <xsd:annotation> <xsd:documentation xml:lang="en"> XML Schema for sending messages to SCXML processors. Version 1.0 </xsd:documentation> <xsd:documentation source="scxml-copyright.xsd" /> </xsd:annotation> <xsd:attributeGroup name="scxmlmessages.extra.attribs"> <xsd:annotation> <xsd:documentation> Group allowing attributes from other namespaces </xsd:documentation> </xsd:annotation> <xsd:anyAttribute namespace="##other" processContents="lax" /> </xsd:attributeGroup> <xsd:attributeGroup name="scxmlmessages.messages.attlist"> <xsd:attribute name="version" type="xsd:string" fixed="1.0" use="required" /> <xsd:attributeGroup ref="scxmlmessages.extra.attribs" /> </xsd:attributeGroup> <xsd:group name="scxmlmessages.messages.content"> <xsd:sequence> <xsd:element ref="message" minOccurs="1" maxOccurs="unbounded" /> </xsd:sequence> </xsd:group> <xsd:complexType name="scxmlmessages.messages.type"> <xsd:group ref="scxmlmessages.messages.content" /> <xsd:attributeGroup ref="scxmlmessages.messages.attlist" /> </xsd:complexType> <xsd:element name="messages" type="scxmlmessages.messages.type" /> </xsd:schema>
The Basic HTTP Event I/O Processor is intended as a minimal interoperable mechanism for sending and receiving events between external components and SCXML 1.0 implementations. Support for the Basic HTTP Event I/O Processor is optional, but implementations that implement this processor MUST support sending and receiving messages in the SCXML message format using it( http://www.w3.org/2011/04/SCXML/scxml-message.xsd ).
The
access
URI
for
the
Basic
HTTP
Event
I/O
Processor
is
the
URI
to
which
an
external
component
can
send
an
event
for
injection
into
an
active
the
current
session.
The
SCXML
Processor
MUST
make
the
access
URI
is
available
via
the
system
variable
_ioprocessors
using
the
key
"basichttp".
For
example,
in
D.2
The
ECMAScript
Data
Model
,
_ioprocessors["basichttp"]
returns
the
access
URI
(e.g.
http://www.example.com/scxml/basichttp)
for
the
basichttp
processor.
An
SCXML
Processor
that
supports
the
Basic
HTTP
Event
I/O
Processor
MUST
accept
messages
from
external
components
at
the
access
URI
as
HTTP
POST
requests
(see
[HTTP]
).
The
SCXML
Processor
MUST
validate
the
message
it
receiveds
and
then
MUST
build
the
appropriate
SCXML
event
and
MUST
add
it
to
the
appropriate
external
event
queue.
If
the
HTTP
parameter
'_content'
'_scxmleventstruct'
is
present,
the
SCXML
Processor
MUST
interpret
its
value
as
a
message
in
the
SCXML
message
format
(
http://www.w3.org/2011/04/SCXML/scxml-message.xsd
).
The
SCXML
Processor
MUST
)
and
map
such
a
message
it
to
an
SCXML
event
as
described
in
E.1
SCXML
Event
I/O
Processor
.
An
Otherwise,
if
the
parameter
'_scxmleventname'
is
present,
the
SCXML
Processor
MAY
MUST
accept
other
parameters
use
its
value
as
well.
In
such
cases,
the
mapping
name
of
their
values
to
the
SCXML
events
event
that
it
raises.
The
treatment
of
all
other
message
content
is
implementation-specific.
platform-specific.
After it adds the received message to the appropriate event queue, the SCXML Processor MUST then indicate the result to the external component via a success response code 2XX. Note that this response is sent before the event is removed from the queue and processed. In the cases where the message cannot be formed into an SCXML event, the Processor MUST return an HTTP error code as defined in [HTTP] . The following codes are assigned a more specific meaning in the SCXML context:
Events can be sent from the SCXML implementation to an external component with the Basic HTTP Event I/O Processor using the <send> element (see 6.2 <send> ) with the type attribute set to "basichttp" and the target attribute set to the access URI of the external component.
The SCXML Processor MUST attempt deliver the message using HTTP method "POST" and with parameter values encoded by default in an application/x-www-form-urlencoded body (POST method). An SCXML Processor MAY support other encodings, and allow then to be specified in a platform-specific way.
If
the
'event'
parameter
of
<send>
is
defined,
the
SCXML
Processor
MUST
use
its
value
as
the
value
of
the
HTTP
POST
parameter
_scxmleventname.
If
the
namelist
attribute
is
defined,
the
SCXML
Processor
MUST
map
its
variable
names
and
values
to
HTTP
POST
parameters.
If
one
or
more
<param>
children
are
present,
the
SCXML
Processor
MUST
map
their
names
(i.e.
name
attributes)
and
values
to
HTTP
POST
parameters.
If
a
<content>
child
is
present,
the
SCXML
Processor
MUST
map
use
its
value
to
as
the
distinguished
HTTP
parameter
'_content'.
body
of
the
message.
If
the
external
component
returns
any
HTTP
response
code
other
than
2XX,
the
SCXML
Processors
that
support
the
BasicHTTP
Event
I/O
Processor
MUST
place
maintain
a
'location'
field
inside
the
error
error.communication
on
entry
for
the
internal
event
queue
of
Basic
HTTP
Event
I/O
Processor
in
the
session
_ioprocessors
system
variable.
Its
value
MUST
hold
an
address
that
attempted
external
entities
can
use
to
send
communicate
with
this
SCXML
session
using
the
event.
Basic
HTTP
Event
I/O
Processor.
The DOM Event I/O processor handles communication between SCXML markup and markup in other namespaces in mixed-markup XML documents. An example of this would be a document containing both SCXML and HTML markup. In such a case, each language retains its own context and its own independent semantics. (For example, SCXML's event processing algorithm is not affected by the fact that there is HTML markup elsewhere in the document.) It is however useful for the two languages to be able to communicate by sending events back and forth, so that the HTML markup can notify SCXML when the user clicks on a button, and the SCXML markup can notify HTML when it is time to place a certain field in focus, etc. The DOM Event I/O processor handles this communication by means of DOM Events [DOMEvents] , which are a general means for information propagation in XML documents.
The SCXML author can send a DOM event to any node in the document by selecting the DOM Event I/O processor (type="DOM") and specifying the URI of that node as the target. The SCXML Processor MUST populate the attributes of the event with the values specified via "namelist" or <param>. "namelist" or <param>. The Processor MUST ignore items that do not correspond to attributes of the event. If the URI specified is not part of the same document, the SCXML Processor MUST place the error error.communication in the internal event queue.
When a DOM event is targeted at the <scxml> root node, the DOM Event I/O processor MUST convert it into an SCXML event and insert it in the external event queue. It MUST convert the attributes of the DOM event into like-named elements in the data field of the event (see 5.11.1 The Internal Structure of Events for details.) The SCXML Processor MUST ignore DOM events targeted at other nodes in the SCXML markup.
[This section is informative.]
A number of other XML-based state machine notations have been developed, but none serves the same purpose as SCXML. XMI [UML XMI] is a notation developed for representing UML diagrams, including Harel State charts. However it is intended as a machine interchange format and is not readily authorable by humans. ebXML [OASIS ebXML] is a language for business process specification intended to support B2B e-commerce applications. It contains a state machine language that is in some ways similar to the one presented here, but its syntax and semantics are closely tied to its intended use in e-commerce. It is therefore not suitable as a general-purpose state machine language. XTND [XTND] , also called XML Transition Network Definition, is a notation for simple finite state machines but lacks Harel's notions of hierarchical and parallel states and are thus not suitable for a general-purpose state machine that is semantically equivalent to Harel statecharts.
[This section is informative.]
This SCXML document gives an overview of the SCXML language and shows the use of its state machine transition flows:
<?xml version="1.0" encoding="us-ascii"?> <!-- A wrapper state that contains all other states in this file - it represents the complete state machine --> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="Main" datamodel="ecmascript"> <state id="Main"> <!-- its initial state is Test1 --> <initial> <transition target="Test1"/> </initial> <!-- Really simple state showing the basic syntax. --> <state id="Test1"> <initial> <transition target="Test1Sub1"/> </initial> <!-- Runs before we go into the substate --> <onentry> <log expr="'Inside Test1'"/> </onentry> <!-- Here is our first substate --> <state id="Test1Sub1"> <onentry> <log expr="'Inside Test1Sub1.'"/> </onentry> <onexit> <log expr="'Leaving Test1Sub1'"/> </onexit> <!-- Go to Sub2 on Event1 --> <transition event="Event1" target="Test1Sub2"/> </state> <!-- Here is the second substate It is final, so Test1 is done when we get here --> <final id="Test1Sub2"/> <!-- We get this event when we reach Test1Sub2. --> <transition event="Test1.done" target="Test2"/> <!-- We run this on the way out of Test1 --> <onexit> <log expr="'Leaving Test1...'"/> </onexit> </state> <state id="Test2"> <initial> <transition target="Test2Sub1"/> </initial> <!-- This time we reference a state defined in an external file. --> <xi:include href="SCXMLExamples/Test2Sub1.xml" parse="text"/> <final id="Test2Sub2"/> <!-- Test2Sub2 is defined as final, so this event is generated when we reach it --> <transition event="done.state.Test2" next="Test3"/> </state> <state id="Test3"> <initial> <transition target="Test3Sub1"/> </initial> <state id="Test3Sub1"> <onentry> <log expr="'Inside Test3Sub1...'"/> <!-- Send our self an event in 5s --> <send event="'Timer'" delay="'5s'"/> </onentry> <!-- Transition on to Test4. This will exit both us and our parent. --> <transition event="Timer" target="Test4"/> <onexit> <log expr="'Leaving Test3Sub1...'"/> </onexit> </state> <onexit> <log expr="'Leaving Test3...'"/> </onexit> </state> <state id="Test4"> <onentry> <log expr="'Inside Test4...'"/> </onentry> <initial> <transition target="Test4Sub1"/> </initial> <state id="Test4Sub1"> <onexit> <log expr="'Leaving Test4Sub1...'"/> </onexit> <!-- This transition causes the state to exit immediately after entering Test4Sub1. The transition has no event or guard so it is always active --> <transition target="Test5"/> </state> </state> <state id="Test5"> <onentry> <log expr="'Inside Test5...'"/> </onentry> <initial> <transition target="Test5P"/> </initial> <!-- Fire off parallel states. In a more realistic example the parallel substates Test5PSub1 and Test5PSub2 would themselves have substates and would do some real work before transitioning to final substates --> <parallel id="Test5P"> <state id="Test5PSub1" initial="Test5PSub1Final"> <final id="Test5PSub1Final"/> </state> <state id="Test5PSub2" initial="Test5PSub2Final"> <final id="Test5PSub2Final"/> </state> <onexit> <log expr="'all parallel states done'"/> </onexit> </parallel> <!-- The parallel states immediately transition to final substates, so this event is generated immediately. --> <transition event="done.state.Test5P" target="Test6"/> </state> <!-- - This state shows invocation of an external component. - We will use CCXML + VoiceXML actions as an example - as it is a good smoke test to show how it all - fits together. - Note: In a real app you would likely - split this over several states but we - are trying to keep it simple here. --> <state id="Test6" xmlns:ccxml="http://www.w3.org/2002/09/ccxml" xmlns:v3="http://www.w3.org/2005/07/vxml3"> <datamodel> <data name="ccxmlid" expr="32459"/> <date name="v3id" expr="17620"/> <data name="dest" expr="'tel:+18315552020'"/> <data name="src" expr="'helloworld2.vxml'"/> <data name="id" expr="'HelloWorld'"/> </datamodel> <onentry> <!-- Use <send> a message to a CCXML Processor asking it to run createcall --> <send target="ccxmlid" type="basichttp" event="ccxml:createcall" namelist="dest"/> </onentry> <transition event="ccxml:connection.connected"> <!-- Here as a platform-specific extension we use example V3 Custom Action Elements instead of send. The implementation of this logic would be platform-dependent. --> <v3:form id="HelloWorld"> <v3:block><v3:prompt>Hello World!</v3:prompt></v3:block> </v3:form> </transition> <transition event="v3:HelloWorld.done"> <!-- Here we are using the low level <send> element to run a v3 form. Note that the event "v3:HelloWorld.done" is assumed either to be set/sent explicitly by the v3:form code or implicitly by some process outside of the v3:form --> <send target="v3id" type="basichttp" event="v3:formstart" namelist="src id"/> </transition> <transition event="v3:HelloWorld2.done"> <!-- we use _event.data to access data in the event we're processing. Again we assume the v3:HelloWorld2.done is set/sent from outside this document --> <ccxml:disconnect connectionid="_event.data.connectionid"/> </transition> <transition event="ccxml:connection.disconnected" target="Done"/> <transition event="send.failed" target="Done"> <!-- If we get an error event we move to the Done state that is a final state. --> <log expr="'Sending to and External component failed'"/> </transition> <onexit> <log expr="'Finished with external component'"/> </onexit> </state> <!-- This final state is an immediate child of Main - when we get here, Main.done is generated. --> <final id="Done"/> <!-- End of Main > --> </state> </scxml>
The example below shows the implementation of a simple microwave oven using SCXML.
<?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" datamodel="ecmascript" initial="off"> <!-- trivial 5 second microwave oven example --> <datamodel> <data id="cook_time" expr="5"/> <data id="door_closed" expr="true"/> <data id="timer" expr="0"/> </datamodel> <state id="off"> <!-- off state --> <transition event="turn.on" target="on"/> </state> <state id="on"> <initial> <transition target="idle"/> </initial> <!-- on/pause state --> <transition event="turn.off" target="off"/> <transition cond="timer >= cook_time" target="off"/> <state id="idle"> <!-- default immediate transition if door is shut --> <transition cond="door_closed" target="cooking"/> <transition event="door.close" target="cooking"> <assign location="door_closed" expr="true"/> <!-- start cooking --> </transition> </state> <state id="cooking"> <transition event="door.open" target="idle"> <assign location="door_closed" expr="false"/> </transition> <!-- a 'time' event is seen once a second --> <transition event="time"> <assign location="timer" expr="timer + 1"/> </transition> </state> </state> </scxml>
The example below shows the implementation of a simple microwave oven using <parallel> and the SCXML In() predicate.
<?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" datamodel="ecmascript" initial="oven"> <!-- trivial 5 second microwave oven example --> <!-- using parallel and In() predicate --> <datamodel> <data id="cook_time" expr="5"/> <data id="door_closed" expr="true"/> <data id="timer" expr="0"/> </datamodel> <parallel id="oven"> <!-- this region tracks the microwave state and timer --> <state id="engine"> <transition target="off"/> <state id="off"> <!-- off state --> <transition event="turn.on" target="on"/> </state> <state id="on"> <transition target="idle"/> <!-- on/pause state --> <transition event="turn.off" target="off"/> <transition cond="timer >= cook_time" target="off"/> <state id="idle"> <transition cond="In('closed')" target="cooking"/> </state> <state id="cooking"> <transition cond="In('open')" target="idle"/> <!-- a 'time' event is seen once a second --> <transition event="time"> <assign location="timer" expr="timer + 1"/> </transition> </state> </state> </state> <!-- this region tracks the microwave door state --> <state id="door"> <initial> <transition target="closed"/> </initial> <state id="closed"> <transition event="door.open" target="open"/> </state> <state id="open"> <transition event="door.close" target="closed"/> </state> </state> </parallel> </scxml>
The example below shows the implementation of a simple calculator in SCXML.
<?xml version="1.0" ?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="on" datamodel="ecmascript" name="calc"> <datamodel> <data id="long_expr" /> <data id="short_expr" expr="0" /> <data id="res" /> </datamodel> <state id="wrapper" initial="on"> <state id="on" initial="ready"> <onentry> <send event="DISPLAY.UPDATE" /> </onentry> <state id="ready" initial="begin"> <state id="begin"> <transition event="OPER.MINUS" target="negated1" /> <onentry> <send event="DISPLAY.UPDATE" /> </onentry> </state> <state id="result"> </state> <transition event="OPER" target="opEntered" /> <transition event="DIGIT.0" target="zero1"> <assign location="short_expr" expr="''" /> </transition> <transition event="DIGIT" target="int1"> <assign location="short_expr" expr="''" /> </transition> <transition event="POINT" target="frac1"> <assign location="short_expr" expr="''" /> </transition> </state> <state id="negated1"> <onentry> <assign location="short_expr" expr="'-'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT.0" target="zero1" /> <transition event="DIGIT" target="int1" /> <transition event="POINT" target="frac1" /> </state> <state id="operand1"> <state id="zero1"> <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int1" /> <transition event="POINT" target="frac1" /> </state> <state id="int1"> <transition event="POINT" target="frac1" /> <transition event="DIGIT"> <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </onentry> </state> <state id="frac1"> <onentry> <assign location="short_expr" expr="short_expr+'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> </state> <transition event="OPER" target="opEntered" /> </state> <state id="opEntered"> <transition event="OPER.MINUS" target="negated2" /> <transition event="POINT" target="frac2" /> <transition event="DIGIT.0" target="zero2" /> <transition event="DIGIT" target="int2" /> <onentry> <raise event="CALC.SUB" /> <send target="_internal" event="OP.INSERT"> <param name="operator" expr="_event.name" /> </send> </onentry> </state> <state id="negated2"> <onentry> <assign location="short_expr" expr="'-'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT.0" target="zero2" /> <transition event="DIGIT" target="int2" /> <transition event="POINT" target="frac2" /> </state> <state id="operand2"> <state id="zero2"> <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int2" /> <transition event="POINT" target="frac2" /> </state> <state id="int2"> <transition event="DIGIT"> <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="POINT" target="frac2" /> </state> <state id="frac2"> <onentry> <assign location="short_expr" expr="short_expr +'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign location="short_expr" expr="short_expr +_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> </state> <transition event="OPER" target="opEntered"> <raise event="CALC.SUB" /> <raise event="OP.INSERT" /> </transition> <transition event="EQUALS" target="result"> <raise event="CALC.SUB" /> <raise event="CALC.DO" /> </transition> </state> <transition event="C" target="on" /> </state> <transition event="CALC.DO"> <assign location="short_expr" expr="''+ res" /> <assign location="long_expr" expr="''" /> <assign location="res" expr="0" /> </transition> <transition event="CALC.SUB"> <if cond="short_expr!=''"> <assign location="long_expr" expr="long_expr+'('+short_expr+')'" /> </if> <assign location="res" expr="eval(long_expr)" /> <assign location="short_expr" expr="''" /> <send event="DISPLAY.UPDATE" /> </transition> <transition event="DISPLAY.UPDATE"> <log level="0" label="'result'" expr=".short_expr==''?res:short_expr" /> </transition> <transition event="OP.INSERT"> <log level="0" expr="_event.data[0]" /> <if cond="_event.data[0] == 'OPER.PLUS'"> <assign location="long_expr" expr="long_expr+'+'" /> <elseif cond="_event.data[0]=='OPER.MINUS'" /> <assign location="long_expr" expr="long_expr+'-'" /> <elseif cond="_event.data[0]=='OPER.STAR'" /> <assign location="long_expr" expr="long_expr+'*'" /> <elseif cond="_event.data[0]=='OPER.DIV'" /> <assign location="long_expr" expr="long_expr+'/'" /> </if> </transition> </state> </scxml>
The example below, which is from the Apache Shale Project. Shale is a web application framework based on JavaServer Faces (JSF). It's composed of loosely coupled services that provide functionality such as application event callbacks, dialogs with conversation-scoped state, a view technology called Clay, annotation-based functionality to reduce configuration requirements and support for remoting. For more information on Shale please see http://shale.apache.org/ . SCXML is used as a "dialog manager" service in Shale (for details on the integration of SCXML in Shale please see http://shale.apache.org/shale-dialog-scxml/index.html ). It allows Shale application authors to express navigation across multiple JSF views and/or other conversations with users of a JSF application using the SCXML markup notation. The example below describes how the navigation across multiple JSF views can be expressed using SCXML. It also shows how a submachine (edit-profile-config.scxml) can be used within an SCXML file. The binding language used in these examples is EL [EL] , which is the expression language supported in the JSF environment.
<?xml version="1.0" encoding="UTF-8"?> <!-- Dialog definitions for Shale Use Cases Example Web Application written out as SCXML to demonstrate use of Commons SCXML as one of Shale's Dialog Manager implementations. For details, see: http://shale.apache.org/shale-dialog-scxml/ --> <scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:my="http://scxml.example.com/" version="1.0" initial="checkCookie" datamodel="el" > <state id="checkCookie"> <onentry> <my:var name="cookieOutcome" expr="#{profile$logon.check}" /> </onentry> <transition cond="${cookieOutcome eq 'authenticated'}" target="exit"/> <transition cond="${cookieOutcome eq 'unauthenticated'}" target="logon"/> </state> <state id="logon"> <transition event="faces.outcome" cond="${outcome eq 'authenticated'}" target="exit"/> <transition event="faces.outcome" cond="${outcome eq 'create'}" target="createProfile"/> </state> <state id="createProfile" src="edit-profile-config.xml" > <transition event="createProfile.done" cond="${outcome eq 'success' or outcome eq 'cancel'}" target="exit"/> </state> <final id="exit"/> </scxml>
<?xml version="1.0" encoding="UTF-8"?> <!-- Dialog definitions for Shale Use Cases Example Web Application written out as SCXML to demonstrate use of Commons SCXML as one of Shale's Dialog Manager implementations. For details, see: http://shale.apache.org/shale-dialog-scxml/ --> <scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:my="http://scxml.example.com/" version="1.0" initial="edit" datamodel="el"> <state id="edit"> <initial> <transition target="setup"/> </initial> <!-- global transitions (within state "edit") --> <transition event="faces.outcome" cond="${outcome eq 'cancel'}" target="cancel"/> <transition event="faces.outcome" cond="${outcome eq 'finish'}" target="finish"/> <state id="setup"> <onentry> <my:var name="setupOutcome" expr="#{profile$edit.setup}" /> </onentry> <transition cond="${setupOutcome eq 'success'}" target="page1"/> </state> <state id="page1"> <transition event="faces.outcome" cond="${outcome eq 'next'}" target="page2"/> </state> <state id="page2"> <transition event="faces.outcome" cond="${outcome eq 'previous'}" target="page1"/> <transition event="faces.outcome" cond="${outcome eq 'next'}" target="page3"/> </state> <state id="page3"> <transition event="faces.outcome" cond="${outcome eq 'previous'}" target="page2"/> <transition event="faces.outcome" cond="${outcome eq 'next'}" target="editExit"/> </state> </state> <state id="cancel"> <onentry> <my:var name="cancelOutcome" expr="#{profile$edit.cancel}" /> </onentry> <transition cond="${cancelOutcome eq 'success'}" target="editExit"> <my:var name="outcome" expr="cancel"/> </transition> </state> <state id="finish"> <onentry> <my:var name="finishOutcome" expr="#{profile$edit.finish}" /> </onentry> <transition cond="${finishOutcome eq 'username'}" target="page1"/> <transition cond="${finishOutcome eq 'password'}" target="page1"/> <transition cond="${finishOutcome eq 'success'}" target="editExit"> <my:var name="outcome" expr="success"/> </transition> </state> <final id="editExit"/> </scxml>
The following two SCXML documents demonstrate the use of Invoke and finalize. The first example shows the control flow for a voice portal offering traffic reports.
<?xml version="1.0"?> <?access-control allow="*"?> <scxml version="1.0" initial="Intro" datamodel="ecmascript"> <state id="Intro"> <invoke src="dialog.vxml#Intro" type="vxml2"/> <transition event="success" cond="sessionChrome.playAds" target="PlayAds"/> <transition event="success" cond="!sessionChrome.playAds && ANIQuality" target="ShouldGoBack"/> <transition event="success" cond="!sessionChrome.playAds && !ANIQuality" target="StartOver"/> </state> <state id="PlayAds"> <invoke src="dialog.vxml#PlayAds" type="vxml2"/> <transition event="success" cond="ANIQuality" target="ShouldGoBack"/> <transition event="success" cond="!ANIQuality" target="StartOver"/> </state> <state id="StartOver"> <onenter> <script>enterStartOver();</script> </onenter> <invoke src="dialog.vxml#StartOver" type="vxml2"> <param name="gotItFromANI" expr="gotItFromANI"/> <finalize> <script>finalizeStartOver();</script> </finalize> </invoke> <transition event="success" target="ShouldGoBack"/> <transition event="doOver" target="StartOver"/> <transition event="restart" target="Intro"/> <!-- bail out to caller --> </state> <state id="ShouldGoBack"> <invoke src="dialog.vxml#ShouldGoBack" type="vxml2"> <param name="cityState" expr="cityState"/> <param name="gotItFromANI" expr="gotItFromANI"/> <finalize> <script>finalizeShouldGoBack();</script> </finalize> </invoke> <transition event="highWay" target="HighwayReport"/> <transition event="go_back" target="StartOver"/> <transition event="doOver" target="ShouldGoBack"/> <transition event="restart" target="Intro"/> </state> <state id="HighwayReport"> <invoke src="dialog.vxml#HighwayReport" type="vxml2"> <param name="cityState" expr="cityState"/> <param name="gotItFromANI" expr="gotItFromANI"/> <param name="playHRPrompt" expr="playHRPrompt"/> <param name="metroArea" expr="metroArea"/> <finalize> <script>finalizeHighwayReport();</script> </finalize> </invoke> <transition event="highway" target="PlayHighway"/> <transition event="go_back" target="StartOver"/> <transition event="doOver" target="HighwayReport"/> <transition event="fullreport" target="FullReport"/> <transition event="restart" target="Intro"/> </state> <state id="FullReport"> <invoke src="dialog.vxml#FullReport" type="vxml2"> <param name="cityState" expr="cityState"/> <param name="metroArea" expr="metroArea"/> <finalize> <script>finalizeFullReport();</script> </finalize> </invoke> <transition event="go_back" target="HighwayReport"/> <transition event="new_city" target="StartOver"/> </state> <state id="PlayHighway"> <invoke src="dialog.vxml#PlayHighway" type="vxml2"> <param name="cityState" expr="cityState"/> <param name="curHighway" expr="curHighway"/> <finalize> <script>finalizePlayHighway();</script> </finalize> </invoke> <transition event="go_back" target="HighwayReport"/> </state> </scxml>
The following example shows a the control flow for a blackjack game.
<?xml version="1.0"?> <?access-control allow="*"?> <scxml version="1.0" datamodel="ecmascript" initial="master"> <state id="master"> <initial id="init1"> <transition target="_home"/> </initial> <transition event="new_dealer" target="NewDealer"/> <transition event="mumble" target="_home"/> <!-- bail out to caller --> <transition event="silence" target="_home"/> <!-- bail out to caller --> <state id="_home"> <onenter> <script> _data = {}; </script> </onenter> <invoke src="datamodel.v3#InitDataModel" type="vxml3"> <finalize> <script> var n; for (n in event) { _data[n] = event[n]; } </script> </finalize> </invoke> <transition event="success" target="Welcome"/> </state> <state id="Welcome"> <invoke src="dialog.vxml#Welcome" type="vxml3"> <param name="skinpath" expr="skinpath"/> </invoke> <transition event="success" target="Intro2"/> </state> <state id="Intro2"> <invoke src="dialog.vxml#Intro2" type="vxml3"> <param name="skinpath" expr="skinpath"/> </invoke> <transition event="success" target="EvalDeal"/> </state> <state id="EvalDeal"> <onenter> <script>enterEvalDeal();</script> </onenter> <invoke src="dialog.vxml#EvalDeal" type="vxml3"> <param name="skinpath" expr="skinpath"/> <param name="playercard1" expr="playercard1"/> <param name="playercard2" expr="playercard2"/> <param name="playertotal" expr="blackjack.GetTotalOf('caller').toString()"/> <param name="dealercardshowing" expr="dealercardshowing"/> </invoke> <transition event="success" target="AskHit"/> </state> <state id="AskHit"> <invoke src="dialog.vxml#AskHit" type="vxml3"> <param name="skinpath" expr="skinpath"/> <finalize> <script>finalizeAskHit();</script> </finalize> </invoke> <transition event="hit" target="PlayNewCard"/> <transition event="stand" target="PlayDone"/> </state> <state id="PlayNewCard"> <invoke src="dialog.vxml#PlayNewCard" type="vxml3"> <param name="skinpath" expr="skinpath"/> <param name="playernewcard" expr="playernewcard"/> <param name="playertotal" expr="blackjack.GetTotalOf('caller').toString()"/> </invoke> <transition event="success" cond="blackjack.GetTotalOf('caller') >= 21" target="PlayDone"/> <transition event="success" target="AskHit"/> <!-- less than 21 --> </state> <state id="PlayDone"> <onenter> <script>enterPlayDone();</script> </onenter> <invoke src="dialog.vxml#PlayDone" type="vxml3"> <param name="skinpath" expr="skinpath"/> <param name="gameresult" expr="blackjack.GetGameResult()"/> <param name="dealertotal" expr="blackjack.GetTotalOf('dealer').toString()"/> </invoke> <transition event="playagain" target="Intro2"/> <transition event="quit" target="_home"/> </state> <state id="NewDealer"> <onenter> <script>enterNewDealer();</script> </onenter> <invoke src="dialog.vxml#Dummy" type="vxml3"/> <transition event="success" target="Welcome"/> </state> </state> </scxml>
Since SCXML documents are XML documents, normal XML namespace rules apply to inline content specified with <content> and <data>. In particular, if no namespace is specified, the inline content will be placed in the SCXML namespace. Consider the following example:
<send target="http://example.com/send/target" type="'basichttp'"> <content> <a>fffff</a> </content> </send>
The recipient of the message will see the following:
<a xmlns="http://www.w3.org/2005/07/scxml">fffff</a>
The following markup would cause the message to be delivered without namespaces:
<send target="http://example.com/send/target" type="'basichttp'"> <content> <a xmlns="">fffff</a> </content> </send>
The recipient of the message will see the following:
<a>fffff</a>
The sender can also specify multiple namespaces:
<send target="http://example.com/send/target" type="'basichttp'"> <content> <root xmlns="http://example.com/r" xmlns:a="http://example.com/a" xmlns:b="http://example.com/b" xmlns:c="http://example.com/c"> <a:alpha>1</a:alpha> <b:beta>2</b:beta> <c:gamma>3</c:gamma> </root> </content> </send>
In this case, the receiver would see:
<root xmlns="http://example.com/r"> <alpha xmlns="http://example.com/a">1</alpha> <beta xmlns="http://example.com/b>2</beta> <gamma xmlns="http://example.com/c>3</gamma> </root>
Custom Action Elements can be defined in other specifications/namespaces and are responsible for performing actions on behalf of custom components. Logically Custom Action Elements can be thought of as a collection of actions and handlers to perform specific tasks. An example of this is a CCXML <accept> element that is a Custom Action Element:
<transition event="ccxml:connection.alerting"> <ccxml:accept connectionid="_event.data.connectionid"/> </transition>
This could be written using a <send> element using the following syntax:
<datamodel> <data name="connectionid"/> </datamodel> <transition event="ccxml:connection.alerting"> <assign name="connectionid" expr="_event.data.connectionid"/> <send type="ccxml" event="ccxml:accept" namelist="connectionid"/> </transition>
A more complicated example might be a CCXML <createcall> where you are both providing variables and getting values back that using only the <send> syntax would be more complex as it would need to be broken over several steps. For example:
<onentry> <ccxml:createcall dest="'tel:+18315552020'" connectionid="myConnectionID"/> </onentry>
Would need to be modeled in two steps using <send> as you would need to do something like the following:
<datamodel> <data name="dest" expr="'tel:+18315552020'"/> <data name="connectionid"/> </datamodel> <onentry> <send type="ccxml" event="ccxml:createcall" namelist="dest"/> </onentry> <transition event="ccxml:createcall.success"> <assign name="connectionid" expr="_event.data.connectionid"/> </transition>
The exact mappings between Custom Action Elements and <send> actions are to be defined in the individual Custom Action Element specifications.
[This section is normative.]
This appendix registers a new MIME media type, "application/scxml+xml".
application
scxml+xml
charset
charset
parameter
of
the
application/xml
media
type
as
specified
in
[RFC
3023]
or
its
successor.
application/scxml+xml
"
may
describe
content
that
has
security
implications
beyond
those
described
here.
However,
if
the
processor
follows
only
the
normative
semantics
of
this
specification,
this
content
will
be
ignored.
Only
in
the
case
where
the
processor
recognizes
and
processes
the
additional
content,
or
where
further
processing
of
that
content
is
dispatched
to
other
processors,
would
security
issues
potentially
arise.
And
in
that
case,
they
would
fall
outside
the
domain
of
this
registration
document.
application/scxml+xml
"
processors
MAY
expect
that
content
received
is
well-formed
XML,
but
processors
SHOULD
NOT
assume
that
the
content
is
valid
SCXML
or
expect
to
recognize
all
of
the
elements
and
attributes
in
the
document.
.scxml
".