Copyright © 2010 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
seventh
eighth
Public
Working
Draft
of
SCXML
published
on
13
May
16
December
2010
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
differences
difference
from
the
previous
draft
are
is
the
removal
of
the
<anchor>
element,
a
revision
of
the
interpretation
algorithm
and
addition
of
a
brief
description
on
DOM
Event
I/O
Processor.
profiles.
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
Module
Constructs
3.1
<scxml>
3.1.1
Attribute
Details
3.1.2
Children
3.1.3
Profile-Dependent
Children
Introduction
3.2
<state>
<scxml>
3.2.1
Attribute
Details
3.2.2
Children
3.2.3
Profile-Dependent
Children
3.3
<transition>
<state>
3.3.1
Attribute
Details
3.3.2
Children
3.3.3
Selecting
and
Executing
Transitions
3.4
<parallel>
<transition>
3.4.1
Attribute
Details
3.4.2
Children
3.4.3
Profile-Dependent
Children
Selecting
and
Executing
Transitions
3.5
<initial>
<parallel>
3.5.1
Attribute
Details
3.5.2
Children
3.6
<final>
<initial>
3.6.1
Attribute
Details
3.6.2
Children
3.7
<donedata>
<final>
3.7.1
Attribute
Details
3.7.2
Children
3.7.3
Profile-Dependent
Children
3.8
<content>
<onentry>
3.8.1
Attribute
Details
3.8.2
Children
3.9
<onentry>
<onexit>
3.9.1
Attribute
Details
3.9.2
Children
3.10
<onexit>
<history>
3.10.1
Attribute
Details
3.10.2
Children
3.11
<history>
Legal
State
Configurations
and
Specifications
3.11.1
Attribute
Details
3.12
SCXML
Events
3.11.2
Children
3.12.1
Event
Descriptors
3.12
3.13
Errors
3.14
IDs
4
Executable
Content
3.12.1
4.1
Introduction
4.2
<raise>
3.12.1.1
4.2.1
Attribute
Details
3.12.1.2
4.2.2
Children
3.12.2
4.3
<if>
3.12.2.1
4.3.1
Attribute
Details
3.12.2.2
4.3.2
Children
3.12.3
4.4
<elseif>
3.12.3.1
4.4.1
Overview
3.12.3.2
4.4.2
Attribute
Details
3.12.4
4.5
<else>
3.12.4.1
4.5.1
Overview
3.12.4.2
4.5.2
Attribute
Details
3.12.5
4.6
<log>
3.12.5.1
4.6.1
Overview
3.12.5.2
4.6.2
Attribute
Details
3.12.5.3
4.6.3
Children
3.12.6
4.7
Profile-Dependent
Other
Executable
Content
3.12.7
Extensibility
4.8
Evaluation
of
Executable
Content
3.13
Referencing
External
Files
3.14
SCXML
Events
4
External
Communications
Module
4.1
<send>
4.1.1
Overview
4.1.2
Attribute
Details
4.1.3
Children
4.1.4
The
Target
of
Send
4.1.5
The
Type
4.9
Extensibility
of
Send
4.1.6
Message
Executable
Content
4.1.7
Send
Errors
4.2
<cancel>
4.2.1
Attribute
Details
5
Data
Model
and
Data
Manipulation
4.2.2
Children
5.1
Introduction
4.3
<invoke>
5.2
<datamodel>
4.3.1
5.2.1
Attribute
Details
4.3.2
5.2.2
Children
4.3.3
Data
Sharing
4.3.4
Implementation
4.4
<finalize>
5.3
<data>
4.4.1
5.3.1
Attribute
Details
4.4.2
5.3.2
Children
5
5.3.3
Data
Module
Binding
and
Scoping
5.1
<datamodel>
5.4
<assign>
5.1.1
5.4.1
Attribute
Details
5.1.2
5.4.2
Children
5.2
<data>
5.5
<validate>
5.2.1
5.5.1
Attribute
Details
5.2.2
5.5.2
Children
5.3
<assign>
5.6
<donedata>
5.3.1
5.6.1
Attribute
Details
5.3.2
5.6.2
Children
5.4
<validate>
5.7
<content>
5.4.1
5.7.1
Attribute
Details
5.4.2
5.7.2
Children
5.5
5.8
<param>
5.5.1
5.8.1
Attribute
Details
5.5.2
5.8.2
Children
5.6
System
Variables
5.6.1
The
Internal
Structure
of
Events
6
Script
Module
6.1
5.9
<script>
6.1.1
5.9.1
Attribute
Details
6.1.2
5.9.2
Children
7
5.10
Expressions
7.1
5.10.1
Conditional
Expressions
7.2
5.10.2
Location
Expressions
7.3
5.10.3
Legal
Data
Values
and
Value
Expressions
7.4
5.10.4
Errors
in
Expressions
8
IDs
9
Profiles
9.1
The
Minimal
Profile
9.1.1
Conformance
9.1.2
Core
Module
Requirements
9.1.2.1
Conditional
Expressions
5.11
System
Variables
9.2
5.11.1
The
ECMAScript
Profile
9.2.1
Conformance
9.2.2
Core
Module
Requirements
9.2.2.1
Conditional
Expressions
Internal
Structure
of
Events
9.2.3
Data
Module
Requirements
6
External
Communications
9.2.3.1
Location
Expressions
6.1
Introduction
9.2.3.2
Value
Expressions
6.2
<send>
9.2.3.3
System
Variables
6.2.1
Overview
9.2.4
Script
Module
Requirements
6.2.2
Attribute
Details
9.2.5
Additional
Requirements
6.2.3
Children
9.2.5.1
6.2.4
The
In()
predicate
Target
of
Send
9.3
6.2.5
The
XPath
Profile
Type
of
Send
9.3.1
Conformance
6.2.6
Message
Content
9.3.2
Core
Module
Requirements
6.3
<cancel>
9.3.2.1
Conditional
Expressions
6.3.1
Attribute
Details
9.3.3
Data
Module
Requirements
6.3.2
Children
9.3.3.1
<assign>
Element
Extensions
6.4
<invoke>
9.3.3.2
Location
Expressions
6.4.1
Attribute
Details
9.3.3.3
Value
Expressions
6.4.2
Children
9.3.3.4
System
Variables
6.4.3
Data
Sharing
9.3.4
Additional
Requirements
6.4.4
Implementation
9.3.4.1
The
scxml:In()
predicate
6.5
<finalize>
9.3.5
Examples
6.5.1
Attribute
Details
10
Related
Work
6.5.2
Children
A
Open
Issues
A.1
Iterative
Construct
Schema
is
Missing
A.2
Alternative
Notation
Algorithm
Doesn't
Handle
Internal
Transitions
A.3
illegal
configurations
Iterative
Construct
A.4
error
handling
A.5
Simplification
of
<send>
and
<raise>
A.6
A.5
autoforward
behavior
B
Algorithm
for
SCXML
Interpretation
C
Probabilistic
State
Machines
Schemas
D
Schemas
Conformance
D.1
Utility
Schemas
Conforming
Documents
D.2
Schema
for
Core
Module
Conforming
Processors
D.3
Schema
for
External
Module
E
Data
Models
D.4
Schema
for
E.1
The
Null
Data
Module
Model
D.5
Schema
for
Script
Module
E.1.1
Data
Model
D.6
Minimal
Profile
Schema
E.1.2
Conditional
Expressions
D.7
ECMAScript
Profile
Schema
E.1.3
Location
Expressions
D.8
XPath
Profile
Schema
E.1.4
Value
Expressions
D.9
SCXML
Message
Schema
E.1.5
Scripting
E
Examples
E.1.6
System
Variables
E.1
Language
Overview
E.1.7
Unsupported
Elements
E.2
Microwave
Example
The
ECMAScript
Data
Model
E.2.1
Data
Model
E.2.2
Conditional
Expressions
E.2.3
Location
Expressions
E.2.4
Value
Expressions
E.2.5
System
Variables
E.2.6
Scripting
E.2.7
Unsupported
Elements
E.3
Microwave
Example
(Using
parallel)
The
XPath
Data
Model
E.4
Calculator
Example
E.3.1
Conditional
Expressions
E.5
Shale
Example
E.3.2
Location
Expressions
E.6
Examples
of
Invoke
and
finalize
E.3.3
Value
Expressions
E.7
Custom
Action
E.3.4
System
Variables
E.3.5
Scripting
E.3.6
<assign>
Element
Extension
E.3.7
Unsupported
Elements
F
Conformance
Event
I/O
Processors
G
F.1
SCXML
Event
I/O
Processor
G.1
F.1.1
Examples
H
F.2
Basic
HTTP
Event
I/O
Processor
H.1
F.2.1
Access
URI
H.2
F.2.2
Receiving
Events
H.3
F.2.3
Sending
Events
I
F.3
DOM
Event
I/O
Processor
I.1
F.3.1
Sending
Events
I.2
F.3.2
Receiving
Events
J
G
Related
Work
H
Examples
H.1
Language
Overview
H.2
Microwave
Example
H.3
Microwave
Example
(Using
parallel)
H.4
Calculator
Example
H.5
Shale
Example
H.6
Examples
of
Invoke
and
finalize
H.7
Custom
Action
Elements
I
References
[ Definition : 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] .
This document outlines State Chart XML (SCXML), which is a general-purpose event-based state machine language that can be used in many ways, including:
SCXML
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.0]
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.
The
Core
Module
contains
the
elements
that
define
the
basic
Harel
state
machine.
The
Core
Module
can
be
used
by
itself
(see
9.1
The
Minimal
Profile
),
but
it
will
not
be
able
to
communicate
with
external
entities
or
maintain
an
internal
data
model.
The
schema
for
the
core
module
can
be
found
at
D.2
Schema
for
Core
Module
.
The top-level wrapper element, which carries version information. The actual state machine consists of its children. etc.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
initial | false | none | IDREFS | none |
|
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 must be "http://www.w3.org/2005/07/scxml". | |
version | true | none | decimal | none | The only legal value is "1.0" | |
|
false | none | NMTOKEN |
|
|
The
|
binding | false |
|
"early" | "early", "late" |
| |
exmode | false | enum | "lax" | "lax", "strict" |
Determines
whether
the
|
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.
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
|
initial | false | May not be specified in conjunction with the <initial> element. May only occur in states that have child <state> or <parallel> elements. | IDREFS | none |
|
The
id
of
the
default
initial
state
(or
states)
for
this
state.
|
A complex state, namely one that has <state> or <parallel> children, may specify either an "initial" attribute or an <initial> element, but not both. Either notation can be used to specify the state's default initial state. 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 the first child state in document order.
Transitions
between
states
are
triggered
by
events
and
conditionalized
via
guard-conditions.
The
optional
attribute
"target"
specifies
the
destination
of
the
transition,
which
guard
conditions.
They
may
be
a
<state>
or
a
<parallel>
region.
contain
executable
content,
which
is
executed
when
the
transition
is
taken.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
event | false | At least one of 'event', 'cond' or 'target' must be specified. | NMTOKENS | none |
A
space-separated
list
of
event
|
A
list
of
designators
of
events
that
trigger
this
transition.
The
transition
will
be
taken
only
when
an
event
is
generated
that
matches
a
|
cond | false | At least one of 'event', 'cond' or 'target' must be specified. | Boolean expression |
|
Any boolean expression. |
true
.
See
|
target | false | At least one of 'event', 'cond' or 'target' must be specified. | IDREFS | none |
|
The identifier(s) of the state or parallel region to transition to. If it is omitted, the transition will not cause a change in the state configuration when it is executed. The executable content contained in the transition will still be executed, so the transition will function as a simple event handler. If the target is present and equal to the state containing the transition element, the transition will cause the state machine to leave and then re-enter this state. See B Algorithm for SCXML Interpretation for details. |
type | false | None | 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.4.3 Selecting and Executing Transitions for details. |
If
a
transition
has
both
"event"
'event'
and
"cond"
'cond'
attributes,
it
will
be
taken
selected
only
if
an
event
is
raised
whose
name
matches
the
"event"
'event'
attribute
(see
3.14
SCXML
Events
3.12.1
Event
Descriptors
for
details)
and
the
"cond"
'cond'
condition
evaluates
to
true.
If
the
"event"
clause
'event'
attribute
is
missing,
the
transition
is
taken
whenever
the
"cond"
'cond'
evaluates
to
true.
If
the
"cond"
clause
is
also
empty,
the
transition
is
taken
as
soon
as
the
state
is
entered.
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.
If
in
any
state
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
event
other
than
e
event
occurs.
<state id=s"> <transition event="e" cond="x==1" target="s1"/> <transition event="e" target="s2"/> <transition event="*" target="s3"/> </state>
Note
that
the
data
model
can
be
changed
only
by
the
execution
of
<invoke>
or
executable
content.
Therefore
transitions
with
empty
"event"
conditions
missing
'event'
attributes
need
be
checked
only
1)
upon
arrival
into
a
state,
after
the
completion
of
all
<onentry>
handlers
and
2)
after
an
event
a
transition
has
been
processed
(since
it
may
have
triggered
executable
content
which
could
have
updated
the
data
model).
taken.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
The
behavior
of
a
transition
with
'type'
of
"external"
(the
default)
is
defined
in
terms
of
the
set
of
active
states,
the
transition's
source
state,
which
is
the
state
that
contains
the
transition,
and
the
transition's
target
state(or
states).
(If
the
transition's
target
is
inside
a
<parallel>
region,
it
may
have
multiple
target
states,
otherwise
it
will
have
a
single
one.)
The
least
common
ancestor
(LCA)
of
a
transition
is
defined
to
be
the
innermost
<state>
or
<parallel>
element
that
is
a
proper
ancestor
of
the
transition's
source
state
states),
and
its
target
state(s).
If
there
is
no
such
element,
the
LCA
is
defined
to
be
the
wrapper
<scxml>
element.
(This
will
be
the
case
if
one
or
more
Least
Common
Ancestor
(LCA)
of
the
source
and
target
states
is
a
top-level
state,
i.e.,
one
that
is
a
direct
descendent
of
<scxml>.)
states.
When
a
transition
is
taken,
all
active
states
that
are
proper
descendants
of
the
LCA
are
exited,
exited
in
exit
order
,
starting
with
the
innermost
one(s)
and
working
up
to
the
immediate
descendant(s)
of
the
LCA.
Then
the
state
machine
enters
the
target
state(s),
plus
any
states
that
are
between
it
and
the
LCA,
in
entry
order
starting
with
the
outermost
one
(i.e.,
the
immediate
descendant
of
the
LCA)
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.
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 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 S is neither entered nor exited. For more details see B 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"
'target'
on
a
<transition>
is
omitted,
then
taking
the
transition
has
the
effect
value
of
leaving
'type'
does
not
have
any
effect
and
taking
the
machine
in
transition
does
not
change
the
same
state
after
invoking
any
configuration
but
does
invoke
the
executable
content
that
is
included
in
the
transition.
Such
a
transition
is
equivalent
to
an
'event'
event
handler
in
Harel
State
Table
notation.
Note
that
this
is
different
from
a
<transition>
whose
"target"
'target'
is
its
source
state.
In
the
latter
case,
the
state
is
exited
and
reentered,
triggering
execution
of
its
<onentry>
and
<onexit>
executable
content.
A
state
that
encapsulates
a
set
of
parallel
states
.
The
<parallel>
element
has
<onentry>
and
<onexit>
and
<transition>
elements
analogous
to
<state>.
In
addition,
is
a
state
whose
children
execute
in
parallel.
Like
<state>,
the
<parallel>
element
holds
a
set
contains
<onentry>,
<onexit>,
<transition>,
and
<state>
or
<parallel>
children.
However,
the
semantics
of
<parallel>
are
different.
When
a
<state>
elements
that
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
and
join
at
in
the
<onexit>
handler
of
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
<parallel>
element.
In
particular,
when
event.
(Similarly,
one
child
state
may
take
a
transition
in
reponse
to
an
event,
while
another
child
ignores
it.)
When
all
of
the
parallel
substates
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.
Either
the
<parallel>
element
or
one
of
its
ancestors
can
trigger
a
transition
off
this
event,
at
which
time
the
<onexit>
handler
of
the
element
will
be
executed.
When
the
state
machine
enters
the
parent
<parallel>
state,
it
simultaneously
enters
each
child
state.
Transitions
within
the
individual
child
elements
operate
normally.
However
any
of
the
child
elements
may
take
whenever
a
transition
is
taken
with
a
target
outside
the
<parallel>
element.
When
this
happens,
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
,
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.
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.
In
particular,
when
an
event
is
processed,
it
is
possible
that
each
of
the
parallel
children
takes
a
separate
transition
on
it.
However,
the
parallel
children
process
the
event
in
a
defined,
serial
order,
so
no
conflicts
or
race
conditions
can
occur.
See
B
Algorithm
for
SCXML
Interpretation
for
a
detailed
description
of
the
semantics
<parallel>
and
the
rest
of
SCXML.
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
|
A conformant SCXML document MUST NOT contain any transitions between parallel siblings. Specifically, if states Si and Sj are children of a <parallel> element, no transition may have Si (or a descendant of Si) as its source and Sj (or a descendent of Sj) as its target.
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
only
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
profiles
that
contain
final
states,
the
External
Communications
Module.
See
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">4.4 <finalize><transition event="done.state.p" target="someOtherState"/>for details.<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>
This
element
represents
the
default
initial
state
for
a
complex
state
with
sequential
substates.
<state>
element
(i.e.
one
one
containing
child
<state>
or
<parellel>
elements.
Suppose
<state>
S1
has
child
states
S11,
S12,
and
S13.
If
the
system
is
in
S1,
it
must
also
be
in
one
(and
only
one)
of
S11,
S12,
or
S13.
A
<transition>
in
a
distinct
<state>
S2
may
take
S11,
S12,
or
S13
as
its
"target",
target,
but
it
may
also
simply
specify
the
parent
S1.
In
that
case,
the
<initial>
child
of
S1
specifies
which
of
S11,
S12,
or
S13
the
system
should
transition
to.
The
only
difference
between
the
<initial>
element
and
the
"initial"
'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"
'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
first
child
state
in
document
order
will
be
entered,
and
no
executable
content
will
be
executed.)
As
an
example,
suppose
that
parent
state
S
contains
child
states
S1
and
S2.
If
S
specifies
S1
as
its
default
initial
state
via
the
"initial"
'initial'
attribute,
then
any
transition
that
specifies
S
as
its
target
will
result
in
S
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
the
an
<initial>
tag
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.
<final>
represents
a
final
state
of
a
an
<scxml>
or
compound
state.
Upon
entry
to
<state>
element.
When
the
final
state,
after
completion
state
machine
enters
the
<final>
child
of
a
<state>
element,
the
<onentry>
elements,
SCXML
processor
MUST
after
generate
the
event
done.state.
parentid
id
is
generated,
after
completion
of
the
<onentry>
elements,
where
parentid
id
is
the
id
of
the
parent
compound
state.
When
the
state
machine
reaches
a
top-level
final
state
(namely
one
that
is
a
the
<final>
child
of
<scxml>),
an
<scxml>
element,
it
has
finished
processing
and
will
terminate.
In
this
case,
no
event
is
generated
unless
See
B
Algorithm
for
SCXML
Interpretation
for
details.
If
the
SCXML
session
was
triggered
as
the
result
of
by
an
<invoke>
element
in
another
session.
In
this
case,
session,
the
SCXML
processor
MUST
generate
the
event
done.invoke.state.
done.invoke.
invokeid
id
is
generated
after
termination
and
returned
return
it
to
the
other
session,
where
invokeid
id
is
the
unique
identifier
generated
when
the
<invoke>
element
was
executed.
See
4.3
6.4
<invoke>
for
details.
When
a
state
machine
is
in
a
final
substate
of
a
compound
state,
the
compound
state
is
still
active
and
will
remain
so
until
a
transition
is
taken
that
exits
it.
However
Note,
however,
that
if
the
compound
state,
or
one
of
its
ancestors,
contains
a
transition
triggered
by
the
done.state.
parentid
id
event,
that
the
transition
will
be
taken
as
soon
as
the
final
substate
when
that
event
is
entered.
processed.
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
|
The
<content>
A
wrapper
element
provides
a
general
way
of
specifying
in-line
data.
It
can
be
used
to
identify
data
to
be
included
in
an
event
or
containing
executable
content
to
be
passed
to
an
external
service.
executed
when
the
state
is
entered.
The
child
elements
of
<content>
consist
of
arbitrary
markup
which
will
be
passed
unmodified.
The
markup
may
consist
of
text,
XML
from
any
namespace,
or
a
mixture
of
both.
Profiles
that
contain
the
Data
Module
may
also
use
5.5
<param>
to
compute
such
data
dynamically.
3.9
<onentry>
3.9.1
Attribute
Details
None.
3.9.2
Children
The
children
of
the
<onentry>
handler
consist
of
executable
content
as
defined
in
3.12
4
Executable
Content
.
The
SCXML
processsor
MUST
execute
this
content
right
after
the
containing
state
has
been
entered.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
A wrapper element containing executable content to be executed before the state is exited.
The
children
of
the
<onexit>
handler
consist
of
executable
content
as
defined
in
3.12
4
Executable
Content
.
The
SCXML
processsor
MUST
execute
this
content
right
before
the
containing
state
is
exited.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
The
<history>
pseudo-state
allows
for
'pause
and
resume'
control
flow.
allows
a
state
machine
to
remember
its
state
configuration.
Whenever
a
complex
<state>
or
<parallel>
element
is
exited,
its
<history>
pseudo-state,
pseudo-state(s),
if
present,
records
record
the
state
configuration
at
exit.
Later
a
<transition>
taking
the
<history>
state
as
its
"target"
target
will
return
the
state
machine
to
this
recorded
configuration.
In
effect,
this
allows
the
<state>
to
pick
up
remember
where
it
left
off.
was.
The
'type'
attribute
determines
how
much
of
the
state
configuration
is
recorded.
If
its
value
is
"shallow",
the
<history>
pseudo-state
records
only
the
immediate
child
state(s)
of
the
parent
state.
Thus,
if
the
state
containing
the
<history>
state
is
a
compound
state,
then
the
history
value
will
be
a
single
state.
However,
if
the
parent
state
is
a
<parallel>
state,
the
history
value
will
be
a
set
of
states,
one
for
each
parallel
child
region.
If
'type'
is
set
to
"deep",
the
history
value
consists
of
all
active
atomic
states
that
are
descendants
of
the
parent
state.
In
effect,
a
"shallow"
history
state
allows
the
parent
state
to
restart
the
child
state(s)
that
were
active
when
it
was
last
exited,
without
regard
to
where
it
was
within
that
child
state,
while
"deep"
history
allows
the
state
to
restart
exactly
where
it
was
when
it
was
last
exited.
Note
that
a
given
state
may
have
both
"deep"
and
"shallow"
history
states.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
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
|
|
type | false |
|
|
"deep" or "shallow" |
|
Executable
content
consists
The
state
configuration
of
actions
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
are
performed
as
part
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
(<onentry>
and
<onexit>,
etc.)
Executable
content
occurs
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
blocks,
meaning
that
wherever
executable
content
the
general
case
specify
a
full
legal
state
configuration
since
1)
they
may
occur,
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
arbitrary
number
ancestor
of
elements
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
occur.
These
elements
in
itself
be
non-atomic.)
In
a
block
are
processed
in
document
order.
If
conformant
SCXML
document,
the
processing
value
of
an
element
causes
'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
error
to
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
raised,
descendants
of
the
remaining
elements
containing
<state>
element.
Events
are
one
of
the
block
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
not
processed
mandatory
and
generated
automatically
by
the
interpreter.
In
this
version
of
the
specification,
in
addition
to
error
events
(see
3.13
Errors
),
there
are
done.state.
id
(see
3.7
<final>
),
cancel.send.
id
(see
6.3
<cancel>
),
done.invoke.
id
and
cancel.invoke.
id
(see
6.4
<invoke>
).
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
placed
on
a
series
of
alphanumeric
characters
segemented
into
tokens
by
the
internal
"."
character.
The
'event'
attribute
of
a
transition
consists
of
one
or
more
such
event
queue
descriptors
separated
by
spaces.
A
transition
matches
an
event
if
at
least
one
of
its
event
descriptors
matches
the
event's
name.
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
case,
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
like
any
other
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
(see
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
B
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.
There
are
two
general
classes
of
errors
that
can
occur
when
processing
an
SCXML
document.
The
first
are
syntactic
errors.
A
conformant
SCXML
document
is
one
that
obeys
all
the
syntactic
restrictions
defined
in
this
specification.
When
an
SCXML
processor
attempts
to
load
and
initialize
an
SCXML
document
that
contains
syntactic
errors,
it
MUST
reject
the
document
and
SHOULD
signal
an
error
to
the
entity
that
requested
the
execution
of
the
document.
The
means
of
signalling
such
syntactic
errors
are
platform-specific
and
outside
the
scope
of
this
specification,
but
it
is
important
to
note
that
the
SCXML
processor
will
never
execute
an
ill-formed
document.
In
particular,
it
will
never
enter
the
error
event
initial
states
of
such
a
document.
Once
the
SCXML
processor
has
begun
executing
a
well-formed
SCXML
document,
any
errors
that
arise
will
not
be
removed
from
signaled
by
SCXML
events
whose
names
begin
with
'error.'.
These
events
will
be
placed
in
the
internal
event
queue
and
and
processed
until
all
like
any
other
event.
In
particular,
they
are
not
processed
immediately
if
there
are
other
events
preceding
it
in
the
queue
have
been
processed.
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
occuring
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
script,
such
as
those
arising
from
expression
evaluation.
Note
that
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
4
External
Communications
Module
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
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,
the
system
MUST
generate
a
unique
one
automatically
at
document
load
time.
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.
They
must
be
unique
within
the
session,
but
in
the
case
where
the
author
does
not
provide
them,
the
system
will
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
5
Data
Module
6.4.1
Attribute
Details
for
details.
All
other
automatically
generated
ids
may
be
in
any
format,
as
long
as
they
are
unique.
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
6
Script
Module
B
Algorithm
for
SCXML
Interpretation
all
define
additional
for
details.
This
standard
defines
elements
of
executable
content
beyond
those
listed
here.
Thus
which
can
raise
events
4.2
<raise>
,
communicate
with
external
entities
6.2
<send>
,
log
information
4.6
<log>
execute
scripts
5.9
<script>
and
modify
the
exact
set
of
data
model
5.4
<assign>
,
as
well
as
control
constructs
to
conditionalize
execution
4.3
<if>
.
In
addition,
SCXML
implementations
are
allowed
to
define
their
own,
platform-specific
executable
content
available
depends
on
the
profile
(see
9
Profiles
4.9
Extensibility
of
Executable
Content
for
examples).
).
The
<raise>
element
may
be
used
to
raise
raises
an
event
in
the
current
SCXML
session.
The
SCXML
processor
MUST
place
the
event
will
be
added
to
at
the
rear
of
the
session's
internal
event
queue,
but
will
not
be
processed
until
later,
following
the
algorithm
specified
in
B
Algorithm
for
SCXML
Interpretation
.
queue.
Note
in
particular
that
the
event
cannot
will
not
be
processed
until
all
the
current
block
of
executable
content
has
completed
and
all
events
that
are
already
in
the
internal
event
queue
have
been
executed.
processed.
For
example,
if
suppose
the
<raise>
element
occurs
first
in
the
the
<onentry>
handlers
handler
of
a
state,
at
state
S
followed
by
executable
content
elements
ec1
and
ec2.
If
event
e1
is
already
in
the
very
least
internal
event
queue
when
S
is
entered,
the
event
generated
by
<raise>
will
not
be
processed
until
all
the
executable
content
in
the
<onentry>
handler
ec1
and
ec2
have
finished
execution
and
e1
has
completed.
been
processed.
For
details
of
event
processing,
see
B
Algorithm
for
SCXML
Interpretation
.
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. |
<raise>
may
have
one
or
more
<param>
children
or
a
single
<content>
child,
but
not
both.
The
data
specified
by
these
elements
will
be
placed
in
the
_event.data
field
of
the
resulting
event,
but
exact
format
of
Note
that
data
will
be
determined
by
the
profile
(see
9
Profiles
for
details).
<param>
may
not
occur
in
documents
whose
profile
does
not
contain
the
Data
Module.
The
4.1
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.
Furthermore,
because
the
'event'
attribute
of
<raise>
is
of
type
NMTOKEN
rather
than
a
dynamically
evaluated
value
expression,
markup
using
<raise>
may
be
analyzed
statically.
<if>
is
a
container
for
conditionally
executed
elements.
<elseif>
and
<else>
can
optionally
appear
within
an
<if>
as
are
optional
immediate
children,
children
of
<if>.
They
have
no
content
and
serve
to
partition
the
executuable
content
elements
within
the
<if>.
<else>
and
<elseif>
have
no
content.
<else/>
is
equivalent
to
an
<elseif
>
element
whose
"cond"
always
evaluates
to
true.<else>
must
occur
after
all
<elseif>
tags.
Each
partition
within
an
<if>
is
preceded
by
an
element
having
a
"cond"
attribute.
The
initial
partition
is
preceded
by
the
<if>
and
subsequent
partitions
by
<elseif>s
(or
<else>).
<elseif>
or
<else>.
The
SCXML
processor
MUST
execute
the
first
partition
in
document
order
with
a
"cond"
that
evaluates
to
true
is
selected.
<else>
always
evaluates
to
true.
A
partition
MAY
be
empty.
If
an
<if>
has
no
immediate
<elseif>
or
<else>
children,
the
full
contents
of
the
<if>
it
creates
a
single
partition
which
will
be
selected
when
executed
if
the
"cond"
attribute
evaluates
to
true.
A
partition
MAY
be
empty.
<else>
was
chosen
is
equivalent
to
match
similar
concepts
in
other
languages,
and
supports
examples
such
as
an
<elseif
>
element
whose
"cond"
always
evaluates
to
true.
In
a
conformant
SCXML
document,
<else>
MUST
occur
after
all
<elseif>
tags.
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>
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
cond | true | Conditional expression | none | A valid conditional expression |
A
boolean
expression.
See
|
An
<elseif>
partitions
the
content
of
an
<if>,
and
provides
a
condition
that
determines
the
selection
of
whether
the
partition
it
begins.
is
executed.
The
partition
defined
by
an
<elseif>
consists
of
all
executable
content
following
between
the
<elseif>
element
and
the
next
<elseif>,
<else>
or
closing
</if>
tag.
The
SCXML
ptocessor
MUST
execute
the
the
executable
content
in
an
<else>'s
partition
will
be
executed
if
execute
the
executable
content
in
the
<elseif>'s
partition
if
and
only
if
its
"cond"
evaluates
to
true
and
all
preceding
"cond"s
evaluate
to
false.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
cond | true | Conditional expression | none | A valid conditional expression |
An
boolean
expression.
See
|
<else>
is
equivalent
to
an
<elseif/>
<elseif>
with
a
"cond"
that
always
evaluates
to
true.
Thus
The
SCXML
ptocessor
MUST
execute
the
the
executable
content
in
an
<else>'s
partition
will
be
executed
if
and
only
if
all
preceding
"cond"s
evaluate
to
false.
In
a
conformant
SCXML
document
<else>
must
MUST
occur
after
all
<elseif>
partitions.
<log>
allows
an
application
to
generate
a
logging
or
debug
message
which
a
developer
can
use
to
help
in
application
development
or
post-execution
analysis
of
application
performance.
message.
The
manner
in
which
the
message
is
displayed
or
logged
is
platform-dependent.
The
usage
of
label
is
platform-dependent.
The
use
of
<log>
SCXML
processor
MUST
have
insure
that
<log>
has
no
other
side-effects
on
document
interpretation.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
label | false | string |
|
A
character
string
|
||
expr | true | Value expression | none |
An
expression
returning
the
value
to
be
logged.
See
|
The
following
elements
of
executable
content
are
not
defined
elsewhere
in
the
Core
Module
but
may
this
specification.
They
MAY
occur
as
wherever
executable
content
in
profiles
that
contain
the
appropriate
modules.
is
allowed
and
MUST
NOT
occur
anyplace
else.
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
presented
is
not
affected.)
The
SCXML
processor
MUST
execute
the
<onexit>
handlers
of
states
exited
by
a
transition
in
this
specification
represents
exitorder
.
The
SCXML
processor
MUST
execute
executable
content
that
is
contained
in
the
transition
after
the
<onexit>
handlers
of
the
states
being
exited,
and
before
the
<onentry>
handlers
of
the
states
being
entered.
The
SCXML
processor
MUST
execute
the
<onentry>
handlers
of
states
entered
by
a
flexible,
powerful,
minimum
set
transition
in
entry
order
.
(Note
that
all
applications
can
rely
on.
Platforms
targetless
transitions
do
not
exit
and
re-enter
their
source
state,
so
only
the
executable
content
in
the
transition
is
executed.
See
3.4.3
Selecting
and
Executing
Transitions
for
details.)
Events
raised
during
the
processing
of
executable
content
are
free
to
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.13
Errors
and
B
Algorithm
for
SCXML
Interpretation
for
details.
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
may
not
MUST
NOT
cause
transitions
or
any
form
of
change
of
state,
except
state
(except
indirectly,
by
raising
events
that
are
then
caught
by
transitions.
It
is
important
to
remember
trigger
transitions).
Note
that
SCXML
treats
the
executable
content
triggered
by
a
transition
as
a
single
blocking
atomic
operation
and
that
no
events
are
processed
until
all
the
executable
content
has
completed.
For
example,
upon
entering
when
taking
a
state,
transition
into
state
S,
the
SCXML
processor
will
not
process
any
events
or
take
any
transitions
until
all
<onentry>
handlers
in
S
have
finished.
Thus
It
is
thus
important
that
all
executable
content,
including
platform-specific
extensions,
SHOULD
complete
quickly
under
all
circumstances.
A
general
method
for
implementing
extensions
using
the
<send>
element
is
presented
in
E.7
Custom
Action
Elements
below.
execute
swiftly.
Platform-specific
In
a
conformant
SCXML
document
any
extensions
to
executable
content
SHOULD
MUST
NOT
be
defined
in
a
separate
namespace,
not
in
the
'scxml'
namespace.
Note
(Note
that
the
schema
D
C
Schemas
allows
elements
from
arbitrary
namespaces
inside
blocks
of
executable
content.
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
interpretation
behavior
of
the
<accept>
element
is
platform-dependent.
Platforms
that
do
not
support
See
D.2
Conforming
Processors
for
details.
A
general
method
for
implementing
extensions
using
the
<send>
element
will
ignore
it.
is
presented
in
H.7
Custom
Action
Elements
.
[Editor's
Note:
Earlier
versions
The
Data
Model
offers
the
capability
of
this
storing,
reading,
and
modifying
a
set
of
data
that
is
internal
to
the
state
machine.
This
specification
included
does
not
mandate
any
specific
data
model,
but
instead
defines
a
'src'
attribute
on
<state>
and
<parallel>
set
of
abstract
capabilities
that
allowed
can
be
realized
by
various
languages,
such
as
ECMAScript
or
XML/XPath.
Implementations
may
choose
the
body
set
of
data
models
that
they
support.
In
addition
to
the
state
underlying
data
structure,
the
data
model
defines
a
set
of
expression
as
described
in
5.10
Expressions
.
These
expressions
are
used
to
be
copied
refer
to
specific
locations
in
from
another
file.
We
have
removed
this
attribute
because
we
believe
that
the
xinclude
specification
[XInclude]
provides
data
model,
to
compute
values
to
assign
to
those
locations,
and
to
evaluate
boolean
conditions.
Finally,
the
data
model
includes
a
superior,
standards-based
version
set
of
system
variables,
as
defined
in
5.11
System
Variables
,
which
are
automatically
maintained
by
the
same
functionality.
Since
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
XML-based
language,
xinclude
functionality
is
automatically
available.
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 E Data Models .
Events
are
one
<datamodel>
is
a
wrapper
element
which
encapsulates
any
number
of
the
basic
concepts
in
SCXML
since
they
drive
most
transitions.
<data>
elements,
each
of
which
defines
a
single
data
object.
The
internal
structure
exact
nature
of
events
is
platform-specific
as
long
as
the
following
external
interface
is
observed:
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. This attribute may occur only on the highest-level <datamodel> element, namely the one that is a child of <scxml>. The exact nature of the schema depends on the data model language being used. |
The
<data>
element
is
used
to
declare
and
populate
portions
of
the
browser's
processing
nor
datamodel.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
id | true | ID | none |
The
name
of
the
| ||
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.
At
most
one
of
"src"
and
"expr"
may
modify
occur.
If
either
is
present,
then
the
element
MUST
not
have
any
children.
Thus
"src",
"expr"
and
children
are
mutually
exclusive
for
the
<data>
element.
In addition, values for <data> elements that are children of <data> elements that are children of the top-most <datamodel> element can be provided by the environment at instantiation time. The exact mechanism for this is implementation dependent, but values provided at instantiation time override those contained in these <data> elements.
If
the
value
specified
(by
'src',
children,
or
the
environment)
is
not
a
legal
data
value,
an
event
once
it
empty
data
element
is
placed
created
in
queue.
the
data
model
with
the
specified
id.
Note
that
this
implies
that
modifications
what
constitutes
a
legal
data
value
depends
on
the
data
model
language
used.
See
E
Data
Models
for
details.
There
is
a
single
globally
visible
data
model
for
the
entire
state
machine
and
the
SCXML
processor
MUST
allow
any
data
element
to
be
accessed
from
any
state.
Thus
the
event
structure
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
MUST
create
all
data
elements
and
assign
their
initial
values
at
document
initialization
time.
When
'binding'
is
assigned
the
value
"late",
the
scxml
processor
MUST
create
the
data
elements
at
document
initialization
time,
but
MUST
assign
the
initial
value
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.)
Ordering
dependencies
between
<data>
elements
are
not
permitted.
In
profiles
which
contain
the
Data
module,
events
case
of
early
binding,
the
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
contain
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
MUST
create
data
model
elements
at
initialization
time
but
MAY
do
so
in
any
order
it
chooses.
Similarly,
the
processor
MUST
assign
the
initial
value
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
MUST
insure
that
can
be
accessed
via
such
values
are
changed
only
by
the
'event'
variable,
as
specified
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.
See
5.6
5.11
System
Variables
.
Events
have
names
for
details.
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
| |
expr | false |
This
attribute
| value expression | none | Any valid value expression |
An
expression
returning
the
|
The
"event"
attribute
children
of
a
transition
consists
the
<assign>element
provide
an
in-line
specification
of
one
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
more
event
designators
separated
children
of
<assign>,
but
not
both.
Assignment
to
a
data
model
is
done
by
spaces.
A
transition
matches
an
event
if
one
using
a
location
expression
to
denote
the
part
of
its
event
designators
the
data
model
where
the
change
is
identical
to
be
made.
If
the
event's
name
location
expression
does
not
denote
a
valid
location
in
the
datamodel
or
if
it
the
value
specified
(
by
'expr'
or
children)
is
not
a
sequence
of
tokens
legal
value
for
the
location
specified,
the
processor
MUST
place
the
error
error.execution
in
the
internal
event
queue.
Otherwise,
the
processor
MUST
place
the
specified
value
at
the
specified
location.
Note
that
form
what
constitutes
a
prefix
legal
value
depends
on
the
data
model
language
used.
See
E
Data
Models
for
details.
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
| |
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
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
transition
schema
with
an
"event"
the
"schema"
attribute
of
'error
foo'
will
match
events
named
'error',
'error.send',
'error.send.failed',
etc.
(or
'foo',
'foo.bar'
etc.)
but
would
not
match
events
named
'errors.my.custom'
the
<validate>
element
or
'errorhandler.mistake'
with
the
"schema"
attribute
of
the
<datamodel>
element
(or
'foobar').
For
compatibility
with
CCXML,
and
both).
If
the
<validate>
element
specifies
a
schema,
the
processor
MUST
use
this
schema
to
make
validate
the
prefix
matching
possibly
more
clear
datamodel.
Otherwise,
it
MUST
use
the
value
specified
in
the
<datamodel>
element.
A
wrapper
element
holding
data
to
be
returned
when
a
reader
<final>
state
is
entered.
In
cases
where
the
SCXML
processor
generates
a
'done'
event
upon
entry
into
the
final
state,
it
MUST
place
the
data
specified
by
this
element
in
the
_event.data
field,
but
exact
format
of
that
data
will
be
determined
by
the
datamodel
(see
E
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
document,
processor
SHOULD
return
the
data
to
the
environment
in
an
event
designator
may
also
end
with
implementation-dependent
manner.
A conformant SCXML document MUST specify either a single <content> element or one or more <param> elements as children of <donedata>, but not both. .
A container element holding in-line data to be passed to an external service.
The
child
elements
of
<content>
consist
of
arbitrary
markup
which
MAY
consist
of
text,
XML
from
any
namespace,
or
a
mixture
of
both.
The
use
of
this
markup
depends
on
the
processed
event's
name.
Note
that
context
in
which
the
<content>
element
occurs.
See
5.6
<donedata>
,
6.2
<send>
and
6.4
<invoke>
for
details.
The
<param>
tag
provides
a
transition
with
"event"
general
way
of
'error'
identifying
a
name/key
and
one
a
dynamically
calcuated
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
| value expression | none | Valid value expression |
A
value
expression
(see
5.10.3
Legal
Data
Values
and
Value
Expressions
)
that
is
evaluted
to
provide
the
|
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
|
A
conformant
SCXML
document
MUST
specify
either
the
'expr'
attribute
of
<param>
or
the
'location'
attribute,
but
not
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
MUST
place
the
error
error.execution
on
the
internal
event
designator
consisting
solely
queue
and
MUST
ignore
the
name
and
value.
Otherwise
the
use
of
'*'
can
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.
The
Script
Module
adds
scripting
capability
to
the
state
machine.
A
<script>
element
that
is
a
child
of
<scxml>
is
evaluated
at
document
load
time.
All
other
<script>
elements
are
evaluated
as
part
of
normal
executable
content
evaluation.
The
name
of
any
script
variable
may
be
used
as
a
wildcard
matching
any
sequence
location
expression
(see
5.10.2
Location
Expressions
).
For
an
example
of
tokens
a
data
model
incorporating
scripting,
see
E.2
The
ECMAScript
Data
Model
.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
URI | false | May not occur if the element has children. | none | A valid URI |
Gives
the
location
from
which
|
A
conformant
SCXML
document
MUST
specify
either
the
'src'
attribute
or
child
content,
but
not
both.
If
'src'
is
different
specified,
the
script
is
downloaded
from
a
transition
lacking
the
"event"
attribute
altogether.
Such
an
eventless
transition
does
specified
location
at
load
time.
If
the
script
can
not
match
any
event,
but
will
be
taken
whenever
its
"cond"
attribute
evaluates
to
'true'.
As
shown
downloaded
within
a
platform-specific
timeout
interval,
the
document
is
considered
non-conformant,
and
the
platform
MUST
reject
it.
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
MUST
insure
that
expressions
do
not
contain
side
effects
that
would
effect
the
datamodel
or
the
execution
of
the
state
machine.
The
SCXML
processor
MAY
optimize
expression
evaluation.
Thus
the
SCXML
processor
MAY
not
evaluate
expressions
as
often
as
indicated
in
B
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.
at
the
same
points
in
the
algorithm.
There
When
"late"
data
binding
is
used,
accessing
data
substructure
in
expressions
before
the
corresponding
<data>
element
is
loaded
yields
the
same
execution-time
behavior
as
accessing
non-existent
data
substructure
in
a
class
of
error
events
whose
names
begin
with
'error.'.
They
may
be
raised
loaded
<data>
instance.
Such
behavior
is
defined
by
the
platform,
as
specified
data
expression
language
in
this
document,
or
under
application
control.
They
use.
Conditional
expressions
are
placed
in
used
inside
the
internal
event
queue
'cond'
attribute
of
<transition>,
<if>
and
processed
like
any
other
event.
In
particular,
they
are
<elseif>.
If
a
conditional
expression
does
not
processed
immediately
evaluate
to
a
boolean
value
('true'
or
'false')
or
if
there
are
other
events
its
evaluation
causes
an
error,
the
SCXML
processor
MUST
treat
the
expression
as
if
it
evaluated
to
'false'
and
MUST
place
the
error
'error.execution'
in
the
queue
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
as
its
argument
and
they
are
ignored
returns
true
if
no
transition
the
state
machine
is
found
that
matches
them.
Note
however
in
that
authors
can
arrange
for
otherwise
unhandled
errors
state.
This
predicate
allows
coordination
among
parallel
regions.
Location
expressions
are
used
to
cause
specify
a
location
in
the
interpreter
datamodel
as
part
of
the
<assign>element.
The
exact
nature
of
a
location
depends
on
the
datamodel.
For
example,
in
the
XPath
datamodel
(
E.3
The
XPath
Data
Model
),
the
underlying
data
structure
is
an
XML
tree
and
a
location
expression
must
evaluate
to
exit
by
creating
an
existing
node
or
nodeset
in
the
tree.
If
a
transition
with
"event"
attribute
of
'error'
location
expression
does
not
evaluate
to
a
legal
location,
the
SCXML
processor
MUST
place
the
error
error.execution
in
the
internal
event
queue.
Any
data
model
MUST
specify
the
underlying
data
structure.
For
example,
the
XPath
datamodel
(
E.3
The
XPath
Data
Model
)
defines
the
data
structure
to
be
an
XML
tree.
Such
a
target
specification
of
any
top-level
final
state
(i.e.
one
the
data
structure
implicitly
defines
a
set
of
"legal
data
values",
namely
the
objects
that
is
can
be
part
of
such
a
child
data
structure.
For
an
XML
data
model,
the
set
of
<scxml>).
legal
data
values
consists
of
XML
trees
and
subtrees,
plus
strings
(as
values
of
attributes
or
text
children).
In
conjunction
with
this,
the
datamodel
MUST
define
a
set
of
value
expressions
which
can
be
evaluated
at
runtime
to
return
legal
data
values.
If
such
a
transition
T
is
placed
in
value
expression
does
not
return
a
state
S,
it
will
cause
legal
data
value,
the
SCXML
processor
MUST
place
the
state
machine
to
terminate
on
any
error
that
is
raised
error.execution
in
S
the
internal
event
queue.
The
SCXML
processor
MAY
reject
documents
containing
syntactically
ill-formed
expressions
at
document
load
time,
or
one
of
its
substates
it
MAY
wait
and
is
not
handled
raise
error.execution
at
runtime
when
the
expressions
are
evaluated.
The
SCXML
processor
MUST
raise
errors
caused
by
another
transition
expressions
returning
illegal
values
at
the
points
at
which
B
Algorithm
for
SCXML
Interpretation
indicates
that
the
expressions
are
to
be
evaluated.
Note
that
this
requirement
holds
even
if
the
implementation
is
placed
in
optimizing
expression
evaluation.
The
Data
Module
maintains
a
substate
protected
portion
of
S
or
the
data
model
containing
information
that
may
be
useful
to
applications.
We
refer
to
the
items
in
S
this
special
part
of
the
data
model
as
'system
variables'.
Implementations
MUST
provide
the
following
system
variables,
and
preceding
T
in
document
order.
MAY
support
others.
The
set
of
mandatory
events
system
variables
may
be
expanded
in
future
drafts
versions
of
this
specification.
Furthermore,
it
is
likely
that
there
will
be
distinct
profiles
of
SCXML
Variable
names
beginning
with
'_'
are
reserved
for
system
use.
Developers
MUST
NOT
use
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
applications,
such
as
data
model
depends
on
the
Multi-modal
Interaction
Framework
[W3C
MMI]
language
used.
For
the
exact
location
of
these
variables
in
an
XML
data
model,
see
E.3
The
XPath
Data
Model
.
All
system
variables
are
protected
and
VoiceXML
3.0.
These
profiles
will
define
extensions
any
attempt
to
the
core
language
change
their
values
MUST
fail
and
result
in
the
error
error.illegalassign
being
raised.
Events
have
an
internal
structure
which
will
likely
extend
be
reflected
in
the
set
_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.
It
is
the
responsibility
of
mandatory
events
with
additional
the
SCXML
platform
that
receives
the
events
appropriate
to
fill
in
these
fields
appropriately.
Platforms
SHOULD
convert
data
received
from
external
entities
into
their
local
datamodel
language
if
possible.
If
the
specific
application.
conversion
is
not
possible,
platforms
MAY
ignore
the
event
or
signal
an
error.
Platforms
may
extend
The
following
fields
are
present
in
all
events,
whether
internal
or
external.
The following fields are logically present in all events, but will be filled in only in external events:
The
External
Communications
Module
adds
the
capability
of
sending
allows
an
SCXML
session
to
send
and
receiving
receive
events
from
external
entities,
as
well
as
invoking
and
to
invoke
external
services.
Its
schema
can
be
found
at
D.3
Schema
for
External
Module
6.2
<send>
.
Profiles
that
include
provides
"fire
and
forget"
capability
to
deliver
events
and
data
to
any
destination,
including
other
SCXML
sessions.
The
details
of
event
transport
as
well
as
the
External
Communications
module
MUST
:
Redefine
format
of
the
executable
content
group
to
include
event
and
data
are
determined
by
the
<send>
Event
I/O
Processor
selected.
Each
implementation
will
support
one
or
more
such
processor,
and
<cancel>
elements.
Redefine
the
content
model
author
of
<state>
the
SCXML
markup
can
choose
the
one
that
is
appropriate
for
the
type
of
endpoint
he
is
trying
to
allow
reach.
6.4
<invoke>
offers
a
single
optional
instance
more
tightly
coupled
form
of
<invoke>
communication,
specifically
the
ability
to
occur
as
trigger
a
child
of
an
atomic
platform-defined
service
and
pass
data
to
it.
The
service
will
generate
a
'done'
event
when
it
completes
and,
conversely,
will
be
terminated
automatically
if
the
state
(i.e.,
one
that
has
neither
<state>
or
<parallel>
children.)
machine
leaves
the
state
containing
the
<invoke>
tag.
Events
and
data
returned
from
the
invoked
service
can
be
pre-processed
with
the
6.5
<finalize>
element.
<send> is used to send events and data to external systems, including external SCXML Interpreters, or to raise events in the current SCXML session.
The
target
of
<send>
is
specified
using
the
"target"
and
"type"
attributes.
These
attributes
control
how
the
platform
should
dispatch
the
event
to
its
final
destination.
See
4.1.4
6.2.4
The
Target
of
Send
and
4.1.5
6.2.5
The
Type
of
Send
for
details.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
event | false | May not occur with 'eventexpr'. If the type is 'scxml', either this attribute or 'eventexpr' must be present. | string | none |
A
string
indicating
the
type
of
message
being
generated.
The
string
may
include
alphanumeric
characters
and
the
"."
(dot)
character.
The
first
character
may
not
be
a
dot
or
a
digit.
Message
type
names
are
case-insensitive.
|
|
eventexpr | false | May not occur with 'event'. If the type is 'scxml' either this attribute or 'event' must be present. | Value expression | none | A dynamic alternative to 'event'. 'event' is a static string, while 'eventexpr' is evaluated at runtime and is treated as if it were the value of 'event'. | |
target | false | May 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
|
targetexpr | false | May not occur with 'target' | Value expression | none | An expression evaluating to a valid target URI | A dynamic alternative to 'target'. 'target' is a static string, while 'targetexpr' is evaluated at runtime and is treated as if it were the value of 'target'. |
type | false | May not occur with 'typeexpr' | string | none |
A
token
that
specifies
the
transport
mechanism
for
the
message.
See
|
|
typeexpr | false | May not occur with 'type' | value expression | none | A dynamic alternative to 'type'. 'type' is a static string, while 'typeexpr' is evaluated at runtime and is treated as if it were the value of 'type'. | |
id | false | This attribute may not occur with 'idlocation'. | ID | none | Any valid token |
A
string
literal
to
be
used
as
the
identifier
for
this
instance
of
<send>.
See
|
idlocation | false | This attribute may not occur with 'id'. | Location expression | none | Any valid location expression |
Any
location
expression
evaluating
to
a
data
model
location.
See
|
delay | false | May not occur with 'delayexpr' or when the attribute 'target' has the value "_internal". | string | None | A time designation as defined in CSS2 [CSS2] format |
The
character
string
is
interpreted
as
a
time
interval.
The
send
tag
will
return
immediately,
but
the
message
is
not
dispatched
until
the
delay
interval
elapses.
In
this
case,
all
arguments
to
send
are
evaluated
when
the
send
element
is
first
processed,
and
not
when
the
message
is
actually
dispatched.
Timers
are
useful
for
a
wide
variety
of
programming
tasks,
and
can
be
implemented
using
this
attribute.
Note:
The
queue
for
messages
events
is
maintained
locally.
Any
messages
waiting
to
be
sent
will
be
purged
when
the
session
that
issued
this
request
terminates.
|
delayexpr | false | May 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'. 'delay' is a static string, while 'delayexpr' is evaluated at runtime and is treated as if it were the value of 'delay'. |
namelist | false |
This
attribute
may
not
be
specified
in
conjunction
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
included
with
the
message.
See
|
hints | false | May not occur with 'hintsexpr'. | string | none | The string contains information which may be used by the implementing platform to optimize message transmission. The meaning of these hints is platform-specific. | |
hintsexpr | false | May not occur with 'hints' | Value expression | none | A value expression. | A dynamic alternative to 'hints'. 'hints' is a static string, while 'hintsexpr' is evaluated at runtime and is treated as if it were the value of 'hints'. |
"namelist" and <content> may not co-occur. That is, the developer may specify the content of the event in the following four ways:
The target of the <send> operation is the destination to which the event should be sent. It may be defined by either the 'target' or the 'targetexpr' attribute. Either one can be used to specify the unique identifier of the target. This may be the identifier of another SCXML session. In other cases the value of this attribute will depend on the type of the target. (For example a SIP URL for SIP-INFO messages or a HTTP URL for Web Services). The following special values are defined:
If
neither
the
'target'
nor
the
'targetexpr'
attribute
is
specified,
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,
invalid
supported
or
invalid,
the
system
will
raise
an
error.execution
event.
If
the
target
is
unreachable
by
the
platform,
the
system
will
raise
an
error.send.targetunavailable
error.communication
event.
The
type
of
the
<send>
operation
specifies
the
method
that
should
be
used
to
deliver
the
message
to
its
target.
The
type
may
be
defined
by
either
the
'type'
or
the
'typeexpr'
attribute.
The
type
is
used
in
conjunction
with
the
target
to
determine
how
to
connect
to
the
destination.
The
neither
the
'type'
nor
the
'typeexpr'
is
defined,
a
default
value
of
'scxml'
is
assumed.
If
the
type
specified
is
not
supported,
the
platform
will
raise
the
error
event
error.send.typeinvalid.
error.execution.
A platform must support the following type:
Value | Details |
---|---|
"scxml" | Target is an SCXML session. The transport mechanism is platform-specific. |
For
details
on
the
'scxml'
type,
see
G
F.1
SCXML
Event
I/O
Processor
.
Support for HTTP POST is optional, however platforms that support it must use the following value for the "type" attribute:
Value | Details |
---|---|
"basichttp" | Target is a URL. Data is sent via HTTP POST |
For
details
on
the
'basichttp'
type,
see
H
F.2
Basic
HTTP
Event
I/O
Processor
.
Support for DOM event delivery is optional, however platforms that support it must use the following value for the "type" attribute:
Value | Details |
---|---|
"DOM" | 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'
type,
see
I
F.3
DOM
Event
I/O
Processor
.
Platforms may support other types such as web-services, SIP or basic HTTP GET. However, platforms SHOULD assign such types names beginning with "x-" to signify that they are platform dependent.
<send> may specify the message name via the optional 'event' attribute. Additional content may be specified in one of the three following 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>
The sending SCXML Interpreter MUST not alter the content of the <send> and must send all the data contained within the message to the destination specified in the target attribute of <send>.
If
the
type
specified
for
the
<send>
is
not
supported,
the
platform
will
raise
an
error
event
send.failed.typenotsupported.
stateid.sendid
,
where
stateid
is
the
id
of
the
<state>
containing
the
<send>,
and
sendid
is
the
automatically
generated
id
for
this
instance
of
<send>.
If
no
send
id
is
specified
in
the
<send>
element,
this
part
of
the
event
name
will
be
omitted.
If
the
type
is
valid,
but
the
platform
is
still
unable
to
send
the
message
for
other
reasons,
the
platform
will
raise
an
error
event
send.failed.targetnotfound.
stateid.sendid
,
where
stateid
and
sendid
have
the
same
significance
as
in
the
typenotsupported
event.
In
the
case
of
<send>
elements
with
a
'delay'
attribute,
these
errors
will
be
raised
when
the
delay
interval
has
passed
and
the
platform
actually
attempts
to
send
the
event.
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.
The
<cancel>
element
may
be
used
to
cancel
a
delayed
<send>
event.
The
system
will
attempt
to
cancel
the
pending
event
and
will
raise
an
internal
event
cancel.successful
if
it
succeeds.
Otherwise
it
will
raise
an
error.notallowed
event.
<cancel>
may
be
used
to
cancel
only
events
that
were
raised
by
a
<send>
occurring
in
the
same
document.
Note
that
though
the
system
will
make
its
best
attempt
to
cancel
the
delayed
event,
it
can
not
be
guaranteed
to
succeed.
For
example,
the
event
may
have
already
been
delivered
by
the
time
the
<cancel>
tag
executes.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
sendid | false | Cannot occur with sendidexpr, but one or the other of them must be specified. The event to be canceled must have been generated in the current document. | IDREF | none | The ID of a delayed event | The ID of the event which is to be canceled. |
sendidexpr | false | Cannot occur with sendid, but one or the other of them must be specified | Value Expression | none | Any expression that evaluates to the ID of a delayed event | A dynamic alternative to 'sendid'. 'sendid' is a static string, while 'sendidexpr' is evaluated at runtime and is treated as if it were the value of 'sendid'. |
<invoke> 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> element may 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 the <invoke> element is executed, the platform MUST start a new logical instance of the external service specified in "type" and pass it the data specified by "src", <content>, or <param>. The service instance MAY be local or remote. In addition to the explicit arguments, the platform MUST keep track of the unique invoke id and insure that it is included in all events that the invoked service returns to the invoking machine.
The
external
service
MAY
generate
multiple
events
while
it
is
processing,
but
once
it
has
finished
processing
it
MUST
return
a
special
event
'done.invoke.
invokeid
id
'
to
the
external
event
queue
of
the
invoking
process,
where
invokeid
id
is
the
identifier
for
the
corresponding
<invoke>
element.
The
external
service
MUST
not
generate
any
other
events
after
this
done
event.
If
the
invoking
state
machine
takes
a
transition
out
of
the
state
containing
the
<invoke>
before
it
receives
the
'done.invoke.
stateid.platformid
id
'
event,
it
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.
When parallel states invoke the same external service concurrently, separate instances of the external service will be started. They can be distinguished by their invokeids which are generated as part of the invocation. Similarly, the invoke id 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 B Algorithm for SCXML Interpretation for details.)
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
type | false | May not occur with 'typeexpr'. | NMTOKEN | none | 'scxml', 'vxml2', 'vxml3', 'ccxml', plus other platform-specific values. | A string specifying the type of the external service. Platforms MUST support 'scxml' as a value. Platforms MAY support 'vxml2', which indicates a VoiceXML 2.x interpreter, 'vxml3' which indicates a VoiceXML 3.x interpreter, and 'ccxml', which indicates a CCXML 1.0 interpreter. Platforms MAY support additional values, but they SHOULD name the values beginning with "x-" to signify that they are platform dependent. |
typeexpr | false | May not occur with 'type'. | value expression | none | Any value expression that evaluates to a character string that would be a valid value for 'type'. | A dynamic alternative to 'type'. 'type' is a static string, while 'typeexpr' is evaluated at runtime and is treated as if it were the value of 'type'. |
src | false | May not occur with the 'srcexpr' attribute or the <content> element. | URI | None | Any URI. |
A
URI
that
will
be
passed
to
the
external
service.
See
|
srcexpr | false | May 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'. 'src' is a static string, while 'srcexpr' is evaluated at runtime and is treated as if it were the value of 'src'. |
id | false | May 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
|
idlocation | false | May not occur with the 'id' attribute. | Location expression | none | Any valid location expression |
Any
data
model
expression
evaluating
to
a
data
model
location.
See
|
namelist | false |
|
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
|
autoforward | false | boolean | false | true or false | If 'true', any external events received by the state machine will be forwarded automatically to the invoked external service. |
Note that either the "id" or "idlocation" attribute may be specified, but not both. If the author does not provide an explicit identifier via the "id" attribute, the system will generate one automatically. It will store this identifier in the location specified by "idlocation" if that attribute is present. 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.
When
the
'autoforward'
attribute
is
set
to
true,
the
invoking
process
will
send
an
exact
copy
of
every
external
event
it
receives
to
the
invoked
process.
In
particular
all
the
fields
specified
in
5.6.1
5.11.1
The
Internal
Structure
of
Events
will
have
the
same
values
in
the
forwarded
copy
of
the
event.
The
invoking
process
will
forward
the
event
at
the
point
at
which
it
removes
it
from
the
external
event
queue
for
processing.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
At most one of "src", <param>, and <content>may be specified. However <param> may occur multiple times if it occurs.
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 may also communicate via events. If the 'autoforward' attribute is set to 'true', the invoking state machine will automatically forward a copy of all external events it receives to the external service. The invoking machine will send such events at the same time as it pulls them off the external event queue to process them. Once it has forwarded the copy, the invoking state machine will process the event normally, regardless of how it is handled in the external service.
SCXML
scripts
can
also
use
the
<send>
tag
To
send
messages
to
the
child
process
on
an
ad-hoc
basis.
The
type
should
be
set
to
the
same
value
as
was
used
in
the
original
<invoke>,
while
the
target
should
have
the
special
form
#_
invokeid
,
where
invokeid
is
the
identifier
corresponding
to
the
original
<invoke>
tag.
For
example,
in
a
profile
document
using
ECMAScript
as
the
data
model,
the
following
code
would
invoke
a
VXML
session:
<invoke type="vxml" 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"/>
Finally, in the case where the invoked external service is an SCXML session, it may use <send> with the special target '_parent' and type 'scxml' to send events, possibly containing data, to the invoking state machine.
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:
<finalize>'s children consist of executable content. The content will be invoked on any event that the external service returns after <invoke> has been executed. This executable content will be applied before the system looks for transitions that match the event. In the case of parallel states, only the finalize code in the original invoking state will be executed. Within the executable content, the special variable '_event' may be used to refer to the data contained in the event which is being finalized.
If no executable content is specified, a default canonicalization handler will be invoked which will update the data model with any return values corresponding to <param> elements with missing "expr" attributes. Thus the effect of a <param> element with an empty "expr" attribute coupled with an empty <finalize> element is first to send all or part of the data model to the invoked component and then to update that part of the state machine's data model with the returned values. Note that the automatic update does not take place if the <finalize> element is absent as opposed to empty.
The purpose of the <finalize> code is to enable transformations between the data contained in events returned by the external service and the state machine's data model where the event data may be then stored. It MUST not raise events or invoke external actions. In particular, the <send> and <raise> elements may not occur.
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" profile="ecmascript"><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> ....
The
<data>
element
is
used
to
declare
and
populate
portions
of
the
datamodel.
All
<data>
tags
are
evaluated
exactly
once.
By
default,
all
<data>
tags
are
evaluated
at
initialization
time.
Unless
"late"
binding
is
chosen,
implementations
thus
MUST
evaluate
<data>
elements
at
initialization
time
but
MAY
do
so
in
any
order
they
choose.
Ordering
dependencies
among
<data>
elements
are
thus
not
permitted.
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
reference
the
value
of
"a"
(and
vice-versa).
When
"late"
binding
is
chosen,
implementations
MUST
evaluate
<data>
elements
only
when
the
parent
state
is
entered
for
the
first
time
but
MAY
evaluate
the
state's
<data>
elements
in
any
order
they
choose.
Therefore
ordering
dependencies
are
not
permitted
among
<data>
elements
in
states
that
are
entered
in
the
same
microstep.
Ordering
dependencies
are
permitted
only
among
<data>
elements
in
states
that
are
entered
in
different
microsteps.
In
particular,
the
state
containing
the
dependent
<data>
element
must
be
entered
after
(i.e.
in
a
subsequent
microstep)
the
state
which
contains
the
<data>
element(s)
it
depends
on.
5.2.1
Attribute
Details
Name
Required
Attribute
Constraints
Type
Default
Value
Valid
Values
Description
id
True
ID
none
The
name
of
the
data
item.
See
8
IDs
for
details.
src
false
URI
none
Any
URI
referencing
a
legal
data
value.
See
7.3
Legal
Data
Values
and
Value
Expressions
for
details.
Gives
the
location
from
which
the
data
object
should
be
downloaded.
expr
false
Expression
none
Any
valid
value
expression
Evaluates
to
provide
the
value
of
the
data
item.
See
7.3
Legal
Data
Values
and
Value
Expressions
for
details.
5.2.2
Children
The
children
of
the
<data>
element
represent
an
in-line
specification
of
the
value
of
the
data
object.
At
most
one
of
"src"
and
"expr"
may
occur.
If
either
is
present,
then
the
element
MUST
not
have
any
children.
Thus
"src",
"expr"
and
children
are
mutually
exclusive
inside
the
<data>
element.
In
addition
to
the
"src"
attribute
and
in-line
child
elements,
values
for
the
top-level
<data>
elements
can
be
provided
by
the
environment
at
instantiation
time.
The
exact
mechanism
for
this
No
schema
is
implementation
dependent,
but
values
provided
at
instantiation
time
override
those
contained
in
the
<scxml>
element,
whether
they
are
specified
in-line
or
via
the
"src"
attribute.
If
the
value
specified
(by
'src',
children,
or
the
environment)
is
not
a
legal
data
value,
the
error
error.invaliddata
is
raised
at
load
time,
and
an
empty
data
element
is
created
in
the
data
model
with
the
specified
id.
Note
that
what
constitutes
a
legal
data
value
depends
on
the
data
model
language
used.
See
9
Profiles
for
details.
The
<assign>
element
may
be
used
to
modify
the
data
model.
5.3
<assign>
5.3.1
Attribute
Details
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
7.2
Location
Expressions
for
details.
Note
that
in
the
case
of
an
XML
data
model
(see
9.3
The
XPath
Profile
),
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.
expr
false
value
expression
none
Any
valid
value
expression
An
expression
returning
the
value
to
be
assigned.
See
7.3
Legal
Data
Values
and
Value
Expressions
for
details.
If
'expr'
is
specified,
no
children
are
permitted.
5.3.2
Children
The
children
of
the
<assign>element
provide
an
in-line
specification
of
legal
data
value
(see
7.3
Legal
Data
Values
and
Value
Expressions
)
to
be
inserted
into
the
datamodel
at
the
specified
location.
If
"expr"
is
present,
then
the
element
MUST
not
have
any
children.
Thus
"expr"
and
children
are
mutually
exclusive
inside
the
<assign>
element.
Assignment
to
a
data
model
is
done
by
using
a
location
expression
to
denote
the
part
of
the
data
model
where
the
change
is
to
be
made.
If
the
location
expression
does
not
denote
a
valid
location
in
the
datamodel
an
error
error.illegalloc
is
raised.
If
the
value
specified
(by
'expr'
or
children)
is
not
a
legal
value
for
the
location
specified,
the
error
error.invaliddata
is
raised.
Note
that
what
constitutes
a
legal
value
depends
on
the
data
model
language
used.
See
9
Profiles
for
details.
5.4
<validate>
The
<validate>
element
causes
the
datamodel
to
be
validated.
Note
that
validation
of
the
datamodel
occurs
only
when
explicitly
invoked
by
this
element.
5.4.1
Attribute
Details
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
7.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.
It
is
a
syntactic
error
if
no
schema
is
specified
in
either
element,
and
the
document
will
fail
validation
at
load
time.
5.4.2
Children
None.
5.5
<param>
The
<param>
tag
provides
a
general
way
of
accessing
the
data
model.
It
can
be
used
to
identify
data
to
be
passed
to
an
external
service
or
to
be
included
in
an
event.
5.5.1
Attribute
Details
Name
Required
Attribute
Constraints
Type
Default
Value
Valid
Values
Description
name
true
NMTOKEN
none
A
string
literal
or
a
valid
data
model
location
expression
The
name
of
the
parameter.
It
will
be
passed
unmodified
to
the
external
service.
It
need
not
specify
a
node
in
the
surrounding
data
model.
expr
false
value
expression
none
Valid
value
expression
draft.
An
optional
value
expression
(see
7.3
Legal
Data
Values
and
Value
Expressions
).
If
provided,
this
expression
specifies
the
value
to
pass
to
the
invoked
component.
If
the
'expr'
attribute
is
missing,
the
'name'
attribute
will
be
taken
as
a
data
model
location
expression
(see
7.2
Location
Expressions
)
and
the
value
at
that
location
updated
schema
will
be
accessed.
If
the
'expr'
attribute
is
missing
and
the
'name'
attribute
does
not
refer
to
a
location
provided
in
the
data
model,
an
error
error.illegalloc
will
be
generated.
5.5.2
Children
None.
next
draft.
The
Data
Module
maintains
a
protected
portion
of
the
data
model
containing
information
that
may
be
useful
to
applications.
We
refer
to
the
items
in
this
special
part
of
the
data
model
as
'system
variables'.
Implementations
that
include
the
Data
Module
MUST
provide
the
following
system
variables,
and
MAY
support
others.
_event
.
The
variable
'_event'
is
bound
to
a
structure
containing
the
current
event's
name
and
any
data
contained
in
the
event
(see
5.6.1
The
Internal
Structure
of
Events
.
The
exact
nature
of
the
structure
depends
on
the
datamodel
being
used.
See
9
Profiles
for
details.
The
_event
variable
is
bound
when
an
event
is
pulled
off
the
internal
or
external
event
queue
to
be
processed,
and
remains
bound
to
that
event
until
another
event
is
processed.
When
testing
the
'cond'
attribute
of
a
<transition>
element
that
contains
an
'event'
attribute,
_event
will
always
be
bound
to
the
event
that
the
transition
is
being
matched
against.
If
the
transition
is
selected
to
be
executed,
_event
will
remain
bound
to
that
event
in
the
<onexit>
handlers
of
the
states
being
exited,
the
executable
content
of
the
transition
itself,
and
the
<onentry>
handlers
of
the
states
being
entered.
In
the
case
of
<transition>
elements
that
do
not
contain
an
'event'
attribute
and
the
<onexit>
and
<onentry>
handlers
of
any
states
that
are
exited
or
entered
by
such
transitions,
the
_event
variable
will
not
have
a
predictable
value
since
the
transition
is
not
being
driven
by
an
event.
In
these
cases,
_event
will
be
bound
to
the
last
event
that
triggered
a
transition.
_event
is
unbound
when
the
state
machine
starts
up,
and
is
not
bound
until
an
event
is
processed.
See
B
Algorithm
for
SCXML
Interpretation
for
details.
If
the
data
in
the
event
is
not
a
legal
instance
of
the
data
model
language,
and
the
system
cannot
translate
it
into
one,
then
at
the
point
at
which
the
system
attempts
to
bind
_event,
the
error
error.invaliddata
will
be
raised
and
the
event
data
part
of
the
_event
structure
will
not
be
bound.
The
event's
name
will
still
be
available,
however.
Processing
of
both
the
original
event
and
the
error
event
will
proceed
as
usual.
_sessionid
.
The
variable
_sessionid
is
bound
at
load
time
to
the
system-generated
id
for
the
current
SCXML
session,
which
will
be
of
type
NMTOKEN.
It
remains
bound
until
the
session
terminates.
_name
.
The
variable
_name
is
bound
at
load
time
to
the
name
of
the
state
machine,
which
is
specified
in
the
"name"
attribute
of
the
<scxml>
element.
It
remains
bound
until
the
session
terminates.
_x
.
The
variable
_x
is
the
root
element
for
platform-specific
system
variables.
Any
platform-specific
system
variables
MUST
be
created
underneath
it.
The
exact
structure
of
the
platform-specific
variables
depends
on
the
data
model.
For
example,
in
the
ECMAScript
profile
9.2
The
ECMAScript
Profile
,
'_x'
will
be
a
top-level
ECMAScript
object
and
the
platform-specific
system
variables
will
be
its
properties.
The
set
of
system
variables
may
be
expanded
in
future
versions
version
of
this
specification.
Variable
names
beginning
with
'_'
are
reserved
for
system
use.
Developers
MUST
NOT
use
ids
beginning
with
'_'
in
the
<data>
element.
Platforms
MUST
place
algorithm
treats
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
9.3
The
XPath
Profile
.
All
system
variables
are
protected
and
any
attempt
to
change
their
values
MUST
fail
and
result
in
the
error
error.illegalassign
being
raised.
5.6.1
The
Internal
Structure
of
Events
Events
have
an
internal
structure
which
will
be
reflected
in
the
_event
variable.
Profiles
containing
a
datamodel
can
access
this
structure
and
use
it
to
condition
transitions
(via
boolean
expressions
in
the
'cond'
attribute)
or
to
update
the
datamodel
(via
<assign>),
etc.
It
is
the
responsibility
of
the
SCXML
platform
that
receives
the
events
to
fill
in
these
fields
appropriately.
Platforms
SHOULD
convert
data
received
from
external
entities
into
their
local
datamodel
language
as
if
possible.
If
the
conversion
is
not
possible,
platforms
MAY
ignore
the
event
or
signal
an
error.
The
following
fields
are
present
in
all
events,
whether
internal
or
external.
name
.
This
is
a
character
string
giving
the
name
of
the
event.
It
is
what
is
matched
against
the
'event'
attribute
of
<transition>.
Note
that
'type'="external",
so
transitions
can
do
additional
tests
by
using
the
value
of
this
field
inside
boolean
expressions
in
the
'cond'
attribute.
type
.
This
field
describes
the
event
type.
It
MUST
contain
one
of
an
enumerated
set
of
string
values
consisting
of:
"platform"
(for
events
raised
by
the
platform
itself,
such
as
error
events),
"internal"
(for
events
raised
by
<raise>
and
<send>
with
target
'_internal')
and
"external"
(for
all
other
events).
sendid
.
In
the
case
of
error
events
triggered
by
a
failed
attempt
to
send
an
event,
this
field
will
contain
the
send
id
of
the
triggering
<send>
element.
Otherwise
it
will
be
blank.
The
following
fields
are
logically
present
in
all
events,
but
will
be
filled
in
only
in
external
events:
origin
.
This
a
URI,
equivalent
to
the
'target'
attribute
on
the
<send>
element.
The
combination
of
this
field
with
the
'origintype'
field
SHOULD
allow
the
receiver
of
the
event
to
<send>
a
response
back
to
the
entity
that
originated
this
event.
origintype
.
This
is
a
character
string,
similar
to
the
'type'
attribute
in
<send>
he
combination
of
this
field
with
the
'origin'
field
SHOULD
allow
the
receiver
of
the
event
to
<send>
a
response
back
to
the
entity
that
originated
this
event.
invokeid
.
If
this
event
is
generated
from
an
invoked
child
process,
this
field
will
contain
the
id
of
the
invocation
that
triggered
the
child
process.
Otherwise
it
will
be
blank.
data
.
This
field
contains
whatever
data
the
sending
entity
chose
to
include
in
this
event.
The
receiving
platform
SHOULD
reformat
this
data
to
match
its
data
model,
but
MUST
not
otherwise
modify
it.
6
Script
Module
6.1
<script>
The
Script
Module
adds
scripting
capability
to
the
state
machine.
Its
schema
may
be
found
at
D.5
Schema
for
Script
Module
.
Profiles
including
the
Script
Module
MUST
:
Redefine
the
executable
content
group
to
include
the
<script>
tag.
Redefine
the
<scxml>
element
to
allow
<script>
as
a
child.
A
<script>
element
that
is
a
child
of
<scxml>
is
evaluated
at
document
load
time.
All
other
<script>
elements
are
evaluated
as
part
of
normal
executable
content
evaluation.
In
profiles
that
contain
both
the
Script
Module
and
the
Data
Module,
the
name
of
any
script
variable
may
be
used
as
a
location
expression
(see
7.2
Location
Expressions
).
For
an
example
of
a
profile
incorporating
scripting,
see
9.2
The
ECMAScript
Profile
.
6.1.1
Attribute
Details
None.
6.1.2
Children
The
children
of
the
<script>
element
represent
the
script
code
to
be
executed.
7
Expressions
SCXML
contains
three
types
of
expressions,
as
described
below.
Different
profiles
of
SCXML
will
support
different
languages
for
these
expression
types,
but
certain
properties
of
the
expressions
are
constant
across
profiles
and
are
defined
here.
Expressions
MUST
not
contain
side
effects
that
would
effect
the
datamodel
or
the
execution
of
the
state
machine.
Implementations
MAY
assume
that
expressions
do
not
have
side
effects
when
optimizing
expression
evaluation.
Thus
expressions
may
not
be
evaluated
as
often
as
indicated
in
B
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
yields
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
and
profile
in
use.
7.1
Conditional
Expressions
Conditional
expressions
'type'="internal"
are
used
inside
the
'cond'
attribute
of
<transition>,
<if>
and
<elseif>.
If
a
conditional
expression
does
not
evaluate
to
a
boolean
value
('true'
or
'false')
or
if
its
evaluation
causes
an
error,
the
expression
is
treated
as
if
it
evaluated
to
'false'
and
the
the
error
'error.illegalcond'
is
placed
on
the
internal
event
queue.
The
set
of
operators
in
conditional
expressions
varies
depending
on
the
profile,
but
all
profiles
must
support
the
'In()'
predicate,
which
is
used
to
test
whether
the
state
machine
is
in
a
given
state.
handled
correctly.
This
predicate
allows
coordination
among
parallel
regions.
7.2
Location
Expressions
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
profile.
For
example,
in
the
XPath
Profile
(
9.3
The
XPath
Profile
),
the
underlying
datamodel
is
an
XML
tree
and
a
location
expression
must
evaluate
to
an
existing
node
or
nodeset
in
the
datamodel.
If
a
location
expression
does
not
evaluate
to
a
legal
location,
an
error
error.illegalloc
is
raised.
7.3
Legal
Data
Values
and
Value
Expressions
Any
profile
that
includes
the
Data
Module
must
specify
the
structure
of
the
underlying
data
model.
For
example,
the
XPath
Profile
(
9.3
The
XPath
Profile
)
defines
the
data
model
to
be
an
XML
tree.
Such
a
specification
of
the
data
model
implicitly
defines
a
set
of
"legal
data
values",
namely
the
objects
that
can
be
part
of
such
a
data
model.
For
an
XML
data
model,
the
set
of
legal
data
values
consists
of
XML
trees
and
subtrees,
plus
strings
(as
values
of
attributes
or
text
children).
In
conjunction
with
this,
the
Profile
must
define
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
error
error.illegalvalue
is
raised.
7.4
Errors
in
Expressions
Implementations
MAY
raise
errors
caused
by
syntactically
ill-formed
expressions
at
document
load
time,
or
they
MAY
wait
and
raise
these
errors
at
runtime
when
the
expressions
are
evaluated.
Implementations
MUST
raise
errors
caused
by
expressions
returning
illegal
values
at
the
points
at
which
B
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.
8
IDs
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,
the
system
MUST
generate
a
unique
one
automatically
at
document
load
time.
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.
They
must
be
unique
within
the
session,
but
in
the
case
where
the
author
does
not
provide
them,
the
system
will
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
4.3.1
Attribute
Details
for
details.
All
other
automatically
generated
ids
may
be
in
any
format,
as
long
as
they
are
unique.
9
Profiles
A
profile
defines
a
concrete
realization
of
the
language.
Each
SCXML
document
MUST
specify
the
profile
it
uses.
At
this
point,
implementations
are
required
to
support
only
the
Minimal
profile,
which
defines
the
core
Harel
functionality.
Implementations
MAY
support
other
profiles,
including
the
ECMAScript
and
XPath
profiles
defined
below.
The
ECMAScript
and
XPath
profiles,
though
optional,
are
normative
in
the
sense
that
they
define
how
implementations
that
support
one
of
these
languages
MUST
behave.
The
intent
is
to
insure
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.
To
define
a
profile,
you
must
first
specify
the
list
of
modules
that
the
profile
includes.
This
list
MUST
include
the
Core
module
and
MAY
include
other
ones.
In
addition
to
this
list
you
must:
Specify
the
boolean
expression
language
used
as
the
value
of
the'cond'
attribute
in
<transition>,
<if>
and
<elseif>
This
language
MUST
not
have
side
effects
and
MUST
include
the
predicate
'In',
which
takes
a
single
argument,
the
id
of
a
state
in
the
enclosing
state
machine,
and
returns
'true'
if
the
state
machine
is
in
that
state.
Specify
any
redefinitions
or
extensions
of
elements
or
attributes
in
any
of
the
included
modules.
If
you
include
the
Data
module,
you
MUST
define
the
location
expression
language
that
is
used
as
the
value
of
the
'location'
attribute
of
the
<assign>
tag.
You
MUST
also
define
the
value
expression
language
that
is
used
as
the
value
of
the
'expr'
attribute
of
the
<data>
and
<assign>
elements.
If
you
include
the
External
Communications
module,
you
MUST
define
one
or
more
Event
Processors.
9.1
The
Minimal
Profile
9.1.1
Conformance
The
Minimal
profile
defines
a
stripped
down
state
machine
with
no
external
communications
or
data
model,
but
with
full
Harel
semantics.
Conformant
SCXML
processors
must
implement
the
following
modules:
SCXML
core
module:
see
3
Core
Module
Conformant
documents
must
specify
a
value
of
profile="minimal"
on
the
root
<scxml>
element.
For
the
schema
of
theMinimal
profile,
see
D.6
Minimal
Profile
Schema
.
9.1.2
Core
Module
Requirements
No
elements
or
attributes
are
extended
or
redefined.
For
the
schema
of
the
Minimal
Profile,
see
D.6
Minimal
Profile
Schema
.
9.1.2.1
Conditional
Expressions
The
boolean
expression
language
consists
of
the
In
predicate
only
.
It
has
the
form
'In(
id
)',
where
id
is
the
id
of
a
state
fixed
in
the
enclosing
state
machine.
next
draft.
We are considering adding an iterative construct, such as 'foreach' or 'while', to the executable content in the Core module. Such a construct is not strictly necessary, since iterators can be modeled by conditionalized targetless transitions. For example, to model a 'while' loop with condition C and body B, create an eventless transition with condition C and executable content B. It will keep firing and executing B without leaving its containing state as long as C is true. However, an explicit iterator might permit more succinct state machines. We solicit comments on the usefulness of such a construct.
Originally, when send and raise were proposed, send was for external communication between the SCXML state machine and an external instance (which might be an SCXML state machine or might be something else). Raise was an internal mechanism that allowed a state machine to raise an internal event - even in the absence of an external communication module or in the absence of a data model. The semantics of sending oneself an event and raising an event were further different because when an event is sent using the send tag it always went on the external event queue, and when one raised an event that was always delivered to the internal event queue.
Over time, there were change requests to allow data passing with the raise tag. This is never really strictly necessary since the data model is global and the raised event is internal to the state machine, but it can be convenient if the same transition may not care if it is handling a raised event or an external event or if the data model may be modified in between when an event is raised and when it ends up being handled (due to the presence of other events on the internal event queue).
Over time, there were also change requests to allow the send tag, from the external communications module, to be able to send an event to the internal queue. The special _internal valuer was used in send to achieve this goal. This is never strictly necessary due to the presence of the raise tag, but might be convenient if the send tag used targetexpr where the target is sometimes _internal and sometimes an external resource.
With these change requests the raise and send tags have become more similar and there are some discussions about what should be done. There are some arguments for leaving things as is: namely the raise is lighter weight than the send and could be present even in the absence of the external communications module. However there are arguments for changing the current state of the world as well: namely there are two ways to do the same thing and some people would rather either combine the two tags to make it less confusing or else make the separation more distinct by reverting the functionality in either send or raise or both to keep the two purposes distinct.
The working group is considering these issues and solicits comments from the wider community on which approach they prefer.
When an external process is invoked with @autoforward="true", all events the parent process receives are automatically forwarded to the invoked process. Should this forwarding behavior include events that were sent by the invoked process? For example, if session scxml1 invokes an external process proc2 with @autoforward="true", and proc2 sends an event e1 back to scxml1, should scxml1 send e1 back to proc2, or should autoforwarding apply only to events that did not originate from proc2?
This section presents 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 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.
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 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 setprocedure
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 added.function
diff(set2) // Returns an OrderedSet containing all members of OrderedSet that are not in set2. 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
datamodel;global
configuration;global
previousConfigurationglobal
statesToInvokeglobal
datamodelglobal
internalQueue;global
externalQueue;global
historyValue;global
continue
The following binary predicates are used for determining the order in which states are entered and exited.
// Places ancestors before descendants, using document order to break ties // Places descendants before ancestors, using reverse document order to break tiesname="entryOrder">entryOrder
// Ancestors precede descendants, with document order being used to break tiesname="exitOrder">exitOrder
// Descendants precede ancestors, with reverse document order being used to break ties
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
perform
inplace
expansions
of
states
by
including
SCXML
source
referenced
by
urls
(see
3.13
Referencing
External
Files
)
and
convert
initial
attributes
to
<initial>
container
children
with
transitions
to
the
state
specified
by
the
attribute
(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
variable
to
true.
Finally
call
enterState
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()
configuration = new OrderedSet()
previousConfiguration = new OrderedSet()
statesToInvoke = new OrderedSet()
datamodel = new Datamodel(doc)
executeGlobalScriptElements(doc)
internalQueue = new Queue()
externalQueue = new BlockingQueue()
continue = true
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
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())
mainEventLoop()
procedure
mainEventLoop()
This loop runs until we enter a top-level final state or an external entity cancels processing. In either case 'continue' will be set to false (see EnterStates, below, for termination by entering a top-level final state.)
Each iteration through the loop consists of three main steps: 1) execute any <invoke> tags for states that we entered on the last iteration through the loop 2) 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
procedure mainEventLoop():
while continue:
for state in statesToInvoke:
for inv in state.invoke:
invoke(inv)
statesToInvoke.clear()
previousConfiguration = configuration
externalEvent = externalQueue.dequeue() # this call blocks until an event is available
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 state
applyFinalize(inv, externalEvent)
if inv.autoforward:
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()
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():inFinalState = falsestatesToExit = configuration.toList().sort(exitOrder) for s in statesToExit: for content in s.onexit: executeContent(content) for inv in s.invoke: cancelInvoke(inv)if isFinalState(s) and isScxmlState(s.parent): inFinalState = trueconfiguration.delete(s)if inFinalState: sendDoneEventToParent()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
the
set
of
enabled
transitions.
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 loop
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,
return
the
set
of
enabled
transitions.
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 loop
return enabledTransitions
function
isPreempted(s
transitionList)
Return true if a transition T in transitionList exits an ancestor of state s. In this case, taking T will pull the state machine out of s and thus we say that it preempts the selection of a transition from s. Such preemption will occur only if s is a descendant of a parallel region and T exits that region. If we did not do this preemption check, we could end up in an illegal configuration, namely one in which there were multiple active states that were not all descendants of a common parallel ancestor.
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 preempted
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 let LCA be the least common 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. 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, 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.
[NOTE: this function must be updated to handle transitions with 'type'="internal". It currently treats all transitions as if they were external.]
procedure
exitStates(enabledTransitions):
statesToExit = new OrderedSet()
for t in enabledTransitions:
if t.target:
LCA = findLCA([t.source].append(getTargetStates(t.target)))
for s in configuration:
if isDescendant(s,LCA):
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 let LCA be the least common ancestor state of the source state and target states of t. For each target state s, call statesToEnte. This will add to statesToEnter s plus all states that will have to be entered in order to enter s. (This may include s's ancestors or parallel siblings.) If LCA is a parallel state, call statesToEnter on each of its children.)
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 enterorder. For each state s in the list, first add s to the current configuration, 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 to false as a signal to stop processing.
procedure
enterStates(enabledTransitions): statesToEnter = new OrderedSet() statesForDefaultEntry = new OrderedSet() for t in enabledTransitions: if t.target: LCA = findLCA([t.source].append(getTargetStates(t.target))) for s in getTargetStates(t.target): addStatesToEnter(s,LCA,statesToEnter,statesForDefaultEntry) if isParallelState(LCA): for child in getChildStates(LCA): addStatesToEnter(child,LCA,statesToEnter,statesForDefaultEntry) for s in statesToEnter: statesToInvoke.add(s) statesToEnter = statesToEnter.toList().sort(enterOrder) for s in statesToEnter: configuration.add(s) 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("done.state." + parent.id)internalQueue.enqueue(new Event("done.state." + parent.id, parent.donedata)) if isParallelState(grandparent): if getChildStates(grandparent).every(isInFinalState):internalQueue.enqueue("done.state." + grandparent.id)internalQueue.enqueue(new Event("done.state." + grandparent.id, grandparent.donedata)) for s in configuration: if isFinalState(s) and isScxmlState(s.parent): continue = false
procedure
addStatesToEnter(s,root,statesToEnter,statesForDefaultEntry)
The purpose of this procedure is to add to statesToEnter all states that must be entered as a result of entering state s. Note that this procedure permanently modifies both statesToEnter and statesForDefaultEntry.
First, If s is a history state then add either the history values associated with sor s's default target to statesToEnter. Else (if s is not a history state), add >s to statesToEnter. Then, if s is a parallel state, add each of s's children to statesToEnter. Else, if s is a compound state, add s to statesForDefaultEntry and add its default initial state to statesToEnter. Finally, for each ancestor anc of s, add anc to statesToEnter and if anc is a parallel state, add any child of anc that does not have a descendant on statesToEnter to statesToEnter.
procedure
addStatesToEnter(s,root,statesToEnter,statesForDefaultEntry):
if isHistoryState(s):
if historyValue[s.id]:
for s0 in historyValue[s.id]:
addStatesToEnter(s0,s,statesToEnter,statesForDefaultEntry)
else:
for t in s.transition:
for s0 in getTargetStates(t.target):
addStatesToEnter(s0,s,statesToEnter,statesForDefaultEntry)
else:
statesToEnter.add(s)
if isParallelState(s):
for child in getChildStates(s):
addStatesToEnter(child,s,statesToEnter,statesForDefaultEntry)
elif isCompoundState(s):
statesForDefaultEntry.add(s)
for tState in getTargetStates(s.initial):
addStatesToEnter(tState, s, statesToEnter, statesForDefaultEntry)
for anc in getProperAncestors(s,root):
statesToEnter.add(anc)
if isParallelState(anc):
for pChild in getChildStates(anc):
if not statesToEnter.toList().some(lambda s2: isDescendant(s2,pChild)):
addStatesToEnter(pChild,anc,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
findLCA(stateList)
Return
The
Least
Common
Ancestor
is
the
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
is
never
a
member
of
stateList.
function
findLCA
(stateList): for anc in getProperAncestors(stateList.head(), null): if stateList.tail().every(lambda s: isDescendant(s,anc)): return anc
In
some
applications,
it
[NOTE:
No
schema
is
useful
provided
with
this
draft.
An
updated
schema
will
be
provided
in
the
next
draft.]
This section is normative.
The following conformance requirements hold for all SCXML documents.
A
SCXML
as
long
as
the
executable
content
includes
1.0
processor
is
a
random
number
generator.
user
agent
that
can
parse
and
process
Conforming
SCXML
1.0
documents.
In
a
Conforming
SCXML
1.0
Processor,
the
example
below,
we
use
ECMAScript
XML
parser
MUST
be
able
to
generate
a
random
number
between
0.0
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
<onentry>
handler
syntax
and
semantics
of
state
S1.
S1
has
two
transitions,
both
triggered
by
E1,
going
any
optional
SCXML
elements
described
in
this
document.
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 MAY
When a Conforming SCXML 1.0 Processor encounters a nonconformant document, its behavior is undefined.
There
is,
however,
no
conformance
requirement
with
respect
to
states
S2
performance
characteristics
of
the
SCXML
1.0
Processor.
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
S3.
S1
takes
scripting.
Each
conformant
SCXML
document
MUST
specify
the
first
transition
if
data
model
it
uses.
(Note
that
the
variable
<rand>
"null"
data
model
is
≤
0.3
but
the
second
transition
if
<rand>
is
>
0.3.
Since
<rand>
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
evenly
distributed
between
0.0
to
insure
interoperability
among
all
processors
that
support
ECMAScript,
and
1.0,
S1
will
transition
all
those
that
support
XPath,
without
requiring
all
implementations
to
S2
30%
support
either
of
those
data
model
languages.
The definition of a data model MUST :
The
following
schemas
contain
common
definitions
that
are
used
by
the
schemas
value
"null"
for
specific
modules
and
profiles.
the
'datamodel'
attribute
results
in
an
absent
or
empty
data
model.
In
particular:
scxml-datatypes.xsd
There
is
no
underlying
data
model.
scxml-attribs.xsd
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
returns
'true'
if
that
state
is
in
the
current
state
configuration.
scxml-contentmodels.xsd
There
is
no
location
expression
language.
scxml-module-core.xsd
There
is
no
value
expression
language.
scxml-module-external.xsd
There
is
no
scripting
language.
System variables are not accessible.
None
of
the
elements
defined
in
<!-- invoke -->
<xsd:attributeGroup name="scxml.invoke.attlist">
<xsd:attribute name="type" type="xsd:NMTOKEN" default="scxml"/>
<xsd:attribute name="typeexpr" type="ValueLang.datatype"/>
<xsd:attribute name="src" type="URI.datatype"/>
<xsd:attribute name="srcexpr" type="ValueLang.datatype"/>
<xsd:attribute name="id" type="xsd:NMTOKEN"/>
<xsd:attribute name="idlocation" type="LocLang.datatype"/>
<xsd:attribute name="namelist" type="xsd:string"/>
<xsd:attribute name="autoforward" type="Boolean.datatype" use="optional" default="false"/>
<xsd:attributeGroup ref="scxml.extra.attribs"/>
</xsd:attributeGroup>
<xsd:group name="scxml.invoke.mix">
<xsd:choice>
<xsd:element ref="finalize" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
<xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:group>
<xsd:group name="scxml.invoke.content">
<xsd:sequence>
<xsd:group ref="scxml.invoke.mix" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="scxml.invoke.type">
<xsd:group ref="scxml.invoke.content"/>
<xsd:attributeGroup ref="scxml.invoke.attlist"/>
</xsd:complexType>
<xsd:element name="invoke" type="scxml.invoke.type"/>
5
Data
Model
and
Data
Manipulation
<!-- finalize -->
<xsd:attributeGroup name="scxml.finalize.attlist">
<xsd:attributeGroup ref="scxml.extra.attribs"/>
</xsd:attributeGroup>
<xsd:group name="scxml.finalize.mix">
<xsd:choice>
<!-- MUST be redefined in the profile in order to define the appropriate executable content and datamodel. -->
</xsd:choice>
</xsd:group>
<xsd:group name="scxml.finalize.content">
<xsd:sequence>
<xsd:group ref="scxml.finalize.mix" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="scxml.finalize.type">
<xsd:group ref="scxml.finalize.content"/>
<xsd:attributeGroup ref="scxml.finalize.attlist"/>
</xsd:complexType>
<xsd:element name="finalize" type="scxml.finalize.type"/>
are
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
<!-- cancel -->
<xsd:attributeGroup name="scxml.cancel.attlist">
<xsd:attribute name="sendid" type="xsd:NMTOKEN"/>
<xsd:attribute name="sendidexpr" type="ValueLang.datatype"/>
<xsd:attributeGroup ref="scxml.extra.attribs"/>
</xsd:attributeGroup>
<xsd:group name="scxml.cancel.content">
<xsd:sequence>
<xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="scxml.cancel.type">
<xsd:group ref="scxml.cancel.content"/>
<xsd:attributeGroup ref="scxml.cancel.attlist"/>
</xsd:complexType>
<xsd:element name="cancel" type="scxml.cancel.type"/>
</xsd:schema>
3.2
<scxml>
for
details.
scxml-module-data.xsd
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]
.
scxml-module-script.xsd
In
a
<datamodel>
element,
each
<data>
child
creates
an
ECMAScript
variable
object
whose
name
is
the
value
of
the
"id"
attribute
of
<data>
.
The
value
of
the
variable
is
assigned
by
the
evaluation
one
of
the
following
expressions:
If no value is assigned, the variable has the default value ECMAScript undefined.
Evaluation of JSON expressions and of XML expressions MAY be supported.
The data model MUST be created by the processor upon initialization of the SCXML document.
<?xml version="1.0" encoding="UTF-8"?> <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:annotation> <xsd:documentation> This is the XML Schema script module for SCXML * script The script module defines these elements and their attributes. </xsd:documentation> <xsd:documentation source="scxml-copyright.xsd"/> </xsd:annotation> <xsd:include schemaLocation="scxml-datatypes.xsd"> <xsd:annotation> <xsd:documentation> Includes common SCXML datatypes </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:include schemaLocation="scxml-attribs.xsd"> <xsd:annotation> <xsd:documentation> Includes common SCXML attributes </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:include schemaLocation="scxml-contentmodels.xsd"> <xsd:annotation> <xsd:documentation> This module defines Common content model extensions for SCXML </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:attributeGroup name="scxml.script.attlist"> <!-- Commented out until added to the actual draft. <xsd:attribute name="src" type="URI.datatype"/> <xsd:attribute name="srcexpr" type="ValueLang.datatype"/> <xsd:attribute name="charset" type="xsd:string"/> <xsd:attributeGroup ref="Cache.attribs"/> --> <xsd:attributeGroup ref="scxml.extra.attribs"/> </xsd:attributeGroup> <xsd:group name="scxml.script.content"> <xsd:sequence> <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:group> <xsd:complexType name="scxml.script.type" mixed="true"> <xsd:group ref="scxml.script.content"/> <xsd:attributeGroup ref="scxml.script.attlist"/> </xsd:complexType> <xsd:element name="script" type="scxml.script.type"/> </xsd:schema><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>
scxml-profile-minimum.xsd
This
datamodel
uses
a
single
global
ECMAScript
scope.
ECMAScript
Profile
Schema
expressions
used
in
conditional
expressions
are
converted
into
their
effective
boolean
value
using
the
ToBoolean
operator
as
described
in
Section
9.2
of
[ECMASCRIPT-262]
.
The
expression
allows
read
only
access
to
variables
and
functions.
scxml-profile-ecma.xsd
The
following
example
illustrates
this
usage.
<?xml version="1.0" encoding="UTF-8"?> <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:annotation> <xsd:documentation> This is the XML Schema driver for SCXML 1.0, xpath profile. Please use this namespace for SCXML 1.0 elements: "http://www.w3.org/2005/07/scxml" </xsd:documentation> <xsd:documentation source="scxml-copyright.xsd"/> </xsd:annotation> <xsd:annotation> <xsd:documentation> This is the Schema Driver file for SCXML 1.0, xpath profile This schema + sets the namespace for SCXML 1.0 basic profile + imports external schemas (xml.xsd) + imports SCXML common datatypes, attributes and content models + imports schema modules SCXML 1.0 includes the following Modules SCXML core module SCXML data module SCXML external module </xsd:documentation> </xsd:annotation> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"> <xsd:annotation> <xsd:documentation> This import brings in the XML namespace attributes The XML attributes are used by various modules. </xsd:documentation> </xsd:annotation> </xsd:import> <xsd:include schemaLocation="scxml-datatypes.xsd"> <xsd:annotation> <xsd:documentation> This includes brings in the common data types for SCXML </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:include schemaLocation="scxml-attribs.xsd"> <xsd:annotation> <xsd:documentation> This includes brings in the common attributes for SCXML. </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:redefine schemaLocation="scxml-module-data.xsd"> <xsd:annotation> <xsd:documentation> This imports the data module for SCXML and redefines the following. [1] Redefines assign attribute group to allow dataid </xsd:documentation> </xsd:annotation> <xsd:attributeGroup name="scxml.assign.attlist"> <xsd:choice> <xsd:attributeGroup name="scxml.assign.attlist"/> <xsd:attribute name="dataid" type="xsd:IDREF"/> </xsd:choice> </xsd:attributeGroup> </xsd:redefine> <xsd:redefine schemaLocation="scxml-module-external.xsd"> <xsd:annotation> <xsd:documentation> This imports the external module for SCXML and redefines the following. [1] Redefines send and invoke mix group to allow param [2] Redefines finalize mix group to allow: executable content </xsd:documentation> </xsd:annotation> <xsd:group name="scxml.send.mix"> <xsd:choice> <xsd:group ref="scxml.send.mix"/> <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.invoke.mix"> <xsd:choice> <xsd:group ref="scxml.invoke.mix"/> <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.finalize.mix"> <xsd:choice> <xsd:group ref="scxml.finalize.mix"/> <xsd:group ref="scxml.core.executablecontent"/> </xsd:choice> </xsd:group> </xsd:redefine> <xsd:include schemaLocation="scxml-contentmodels.xsd"> <xsd:annotation> <xsd:documentation> This includes the common content models. </xsd:documentation> </xsd:annotation> </xsd:include> <xsd:redefine schemaLocation="scxml-module-core.xsd"> <xsd:annotation> <xsd:documentation> This imports the core module for SCXML and redefines the following. [1] Redefines executable content to allow send, assign, validate, and cancel elements [2] Redefines state and parallel mix group to allow invoke datamodel [3] Redefines scxml group to allow datamodel </xsd:documentation> </xsd:annotation> <xsd:group name="scxml.core.executablecontent"> <xsd:choice> <xsd:group ref="scxml.core.executablecontent"/> <xsd:element ref="send"/> <xsd:element ref="assign"/> <xsd:element ref="validate"/> <xsd:element ref="cancel"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.state.mix"> <xsd:choice> <xsd:group ref="scxml.state.mix"/> <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="datamodel" minOccurs="0"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.scxml.mix"> <xsd:choice> <xsd:group ref="scxml.scxml.mix"/> <xsd:element ref="datamodel" minOccurs="0"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.parallel.mix"> <xsd:choice> <xsd:group ref="scxml.parallel.mix"/> <xsd:element ref="datamodel" minOccurs="0"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.donedata.mix"> <xsd:choice> <xsd:group ref="scxml.donedata.mix"/> <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:group> <xsd:group name="scxml.raise.mix"> <xsd:choice> <xsd:group ref="scxml.raise.mix"/> <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/> </xsd:choice> </xsd:group> </xsd:redefine> </xsd:schema><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>
scxml-message.xsd
Conditional
expressions
may
take
advantage
of
the
In()
predicate.
A
conformant
SCXML
processor
MUST
add
an
ECMAScript
function
to
the
SCXML
namespace
that
takes
a
stateID
as
its
argument
and
returns
'true'
if
that
state
is
in
the
current
state
configuration,
as
described
in
<xsd:complexType name="scxmlmessage.property.type" mixed="true">
<xsd:group ref="scxmlmessage.property.content" />
<xsd:attributeGroup ref="scxmlmessage.property.attlist" />
</xsd:complexType>
5.10.1
Conditional
Expressions
<xsd:element name="property" type="scxmlmessage.property.type" />
.
Here
is
an
example
of
its
use,
taken
from
<xsd:element name="hint" type="xsd:string" />
H.3
Microwave
Example
(Using
parallel)
</xsd:schema>
below:
<transition cond="In('closed')" target="cooking"/>
This
SCXML
document
gives
ECMAScript
left-hand-side
expressions
are
used
to
select
an
overview
object
(or
sub-property
of
an
object)
from
the
SCXML
language
and
shows
the
use
of
its
state
machine
transition
flows:
data
model
by
providing
a
binding
expression.
The
following
example
illustrates
this
usage:
<?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" profile="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="errorSwitch"> <datamodel> <data id="employees" src="http://example.com/employees.json"/> </datamodel><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><onentry> <assign location="employees.employee[12].salary" expr="42000"/> </onentry> </state>
The result of any ECMAScript expression may be used in a value expression.
<!-- This is an example substate defined in - an external file and included by Main.scxml. --> <state id="Test2Sub1"><state id="processEvent"> <datamodel> <data id="myEvent"/> </datamodel> <onentry><log expr="'Inside Test2Sub1'"/><assign location="myEvent" expr="_event.data"/> </onentry><transition event="Event2" target="Test2Sub2"/> </state></state>
System
variables
are
defined
as
ECMAScript
read-only
variables.
The
example
below
shows
_event
system
variable
is
defined
as
an
object
with
two
properties:
name
(String
value)
for
the
implementation
name
of
the
event;
and
data
(Object
value)
exposing
the
event
data
payload.
The
_sessionid
and
_name
system
variables
are
defined
as
variables
with
ECMAScript
String
values.
The
_sessionid
and
_name
values
MUST
be
set
by
the
processor
at
session
start.
Suppose
as
part
of
executing
a
simple
microwave
oven
using
SCXML.
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 datamodel would have the following form:
<?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" profile="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>{ // The three properties below are automatically populated by the system<!-- a 'time' event is seen once a second --> <transition event="time"> <assign location="timer" expr="timer + 1"/> </transition> </state>"_name" : "myName" , "_sessionid" : "12345" , "_event" : { "name" : "foo.bar" , "data" : { "answer" : 42 } } ,</state>// Rest of the application / developer-authored data model goes here }</scxml>
The
example
below
shows
the
implementation
of
As
an
example,
here
is
a
simple
microwave
oven
using
<parallel>
and
sample
transition
that
accesses
the
SCXML
In()
predicate.
_event
variable
in
that
data
model.
<?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" profile="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><state id="checkEventName"> <transition cond="_event.name=='foo.bar'" target="nextState"> ... </transition> </state>
The
inline
content
of
the
<script>
is
an
ECMAScript
program
as
defined
in
Section
14
of
[ECMASCRIPT-262]
.
<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>
5.5
<validate>
<!-- 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>
is
not
supported
in
the
ECMA
Data
Model.
If
the
SCXML
processor
encounters
a
document
specifying
the
ECMA
Data
Model
and
containing
this
element,
it
MUST
behave
as
instructed
by
the
'exmode'
attribute
on
<scxml>.
See
</parallel>
3.2
<scxml>
</scxml>
for
details.
The
example
below
shows
value
"xpath"
for
the
implementation
of
a
simple
calculator
'datamodel'
attribute
results
in
SCXML.
an
XML
data
model
with
XPath
used
as
the
expression
language.
Implementations
that
support
this
data
model
MUST
support
[XPath
2.0]
.
XPath 2.0 expressions used in conditional expressions are converted into their effective boolean value as described in section 2.4.3 of the [XPath 2.0] specification. The following example illustrates this usage.
<?xml version="1.0" ?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="on" profile="ecmascript" name="calc"> <datamodel> <data id="long_expr" /> <data id="short_expr" expr="0" /> <data id="res" /> </datamodel> <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 dataid="short_expr" expr="''" /> </transition> <transition event="DIGIT" target="int1"> <assign dataid="short_expr" expr="''" /> </transition> <transition event="POINT" target="frac1"> <assign dataid="short_expr" expr="''" /> </transition> </state> <state id="negated1"> <onentry> <assign dataid="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 dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </onentry> </state> <state id="frac1"> <onentry> <assign dataid="short_expr" expr="short_expr+'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign dataid="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 dataid="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 dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign dataid="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 dataid="short_expr" expr="short_expr +'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign dataid="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 dataid="short_expr" expr="''+ res" /> <assign dataid="long_expr" expr="''" /> <assign dataid="res" expr="0" /> </transition> <transition event="CALC.SUB"> <if cond="short_expr!=''"> <assign dataid="long_expr" expr="long_expr+'('+short_expr+')'" /> </if> <assign dataid="res" expr="eval(long_expr)" /> <assign dataid="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 dataid="long_expr" expr="long_expr+'+'" /> <elseif cond="_event.data[0]=='OPER.MINUS'" /> <assign dataid="long_expr" expr="long_expr+'-'" /> <elseif cond="_event.data[0]=='OPER.STAR'" /> <assign dataid="long_expr" expr="long_expr+'*'" /> <elseif cond="_event.data[0]=='OPER.DIV'" /> <assign dataid="long_expr" expr="long_expr+'/'" /> </if> </transition> </scxml><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
example
below,
which
is
from
the
Apache
Shale
Project.
Shale
is
a
web
application
framework
based
on
JavaServer
Faces
(JSF).
It's
composed
Conditional
expressions
may
take
advantage
of
loosely
coupled
services
the
scxml:In()
predicate.
A
conformant
SCXML
processor
MUST
add
an
XPath
function
to
the
SCXML
namespace
that
provide
functionality
such
as
application
event
callbacks,
dialogs
with
conversation-scoped
state,
takes
a
view
technology
called
Clay,
annotation-based
functionality
to
reduce
configuration
requirements
stateID
as
its
argument
and
support
for
remoting.
For
more
information
on
Shale
please
see
http://shale.apache.org/
.
SCXML
returns
'true'
if
that
state
is
used
in
the
current
state
configuration,
as
a
"dialog
manager"
service
described
in
Shale
(for
details
on
5.10.1
Conditional
Expressions
.
For
examples
of
the
integration
use
of
SCXML
this
predicate
(but
in
Shale
please
an
ECMAScript
context),
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
H.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
users
ID
$stateID
is
one
of
a
JSF
application
using
the
SCXML
markup
notation.
The
example
below
describes
how
currently
active
states.
XPath
2.0
expressions
are
used
to
select
a
node-set
from
the
navigation
across
multiple
JSF
views
can
be
expressed
using
SCXML.
It
also
shows
how
data
model
by
providing
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.
expression.
The
following
example
illustrates
this
usage:
<?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.examples.org/" version="1.0" initial="checkCookie" profile="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"/><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></scxml><onentry> <assign location="$cities/list/city[@id='nyc']/@count" expr="1"/> </onentry> </state>
The result of any XPath expression may be used in a value expression. If the result of the value expression is a node-set, a deep copy of the subtree rooted at each node is made.
<?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.examples.org/" version="1.0" initial="edit" profile="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"><state id="processEvent"> <datamodel> <data id="myEventData"/> </datamodel> <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><assign location="$myEventData" expr="$_event/data"/> </onentry> </state>
Within
the
Data
Model,
three
implicit
<data>
elements
are
defined
to
hold
the
system
variables
as
described
in
section
5.6
of
Invoke
the
[XPath
2.0]
specification.
These
are
named
$_event
,
$_sessionid
,
and
finalize
$_name
.
The
following
two
SCXML
documents
demonstrate
$_event
value
MUST
be
assigned
by
processor
before
triggering
executable
content
in
the
use
of
Invoke
<onentry>,
<onexit>,
and
finalize.
<transition>
elements
which
may
reference
the
variable.
The
first
example
shows
processor
MUST
clear
the
control
flow
for
value
by
setting
its
child
elements
<name>
and
<data>
to
empty
XML
elements
when
event
processing
has
completed.
The
$_sessionid
and
$_name
values
MUST
be
set
by
the
processor
at
session
start.
Suppose
as
part
of
executing
a
voice
portal
offering
traffic
reports.
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:
<?xml version="1.0"?> <?access-control allow="*"?> <scxml version="1.0" initial="Intro" profile="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><datamodel><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><!-- The three data elements below are automatically populated by the system --><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><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><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><!-- Rest of the application / developer-authored data model goes here --> </datamodel>
The
following
example
shows
As
an
example,
here
is
a
sample
transition
that
accesses
the
control
flow
for
a
blackjack
game.
$_sessionid
variable
in
that
data
model.
<?xml version="1.0"?> <?access-control allow="*"?> <scxml version="1.0" profile="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><state id="checkSessionid"> <transition cond="$_sessionid = '12345'" target="nextState"/> ... </state>
Custom
Action
Elements
can
be
defined
in
other
specifications/namespaces
and
are
responsible
Implementations
supporting
the
XPath
datamdel
MAY
support
an
additional
attribute
for
performing
actions
on
behalf
the
<assign>
element,
as
shown
below.
Name | Required | Attribute Constraints | Type | Default Value | Valid Values | Description |
---|---|---|---|---|---|---|
dataid | false | IDREF | none |
The
ID
of
|
The
'id'
of
|
Note
that
in
the
case
of
an
XML
data
model,
it
is
not
required
to
assign
to
the
root
of
a
Custom
Action
Element:
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:
<transition event="ccxml:connection.alerting"> <ccxml:accept connectionid="_event.data.connectionid"/> </transition><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>
This
could
be
written
using
Here
is
an
example
of
assignment
of
a
<send>
string
to
an
element
using
the
following
syntax:
node.
<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><assign location="$cart/myCart/books/book[1]/title" expr="'My favorite book'"/>
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:
results
in
<onentry> <ccxml:createcall dest="'tel:+18315552020'" connectionid="myConnectionID"/> </onentry><data id="cart"> <myCart xmlns=""> <books> <book> <title>My favorite book</title> </book> <book> <title>Freakonomics</title> </book> ... </data>
Would
need
Now
suppose
we
assign
an
xml
structure
to
be
modeled
in
two
steps
using
<send>
as
you
an
element
node.
The
following
assignment
statement
would
need
to
do
something
like
have
the
following:
effect
of
replacing
the
children
of
the
element
"$cart/myCart/books/book[1]"
by
the
XML
tree
rooted
in
<bookinfo>.
<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><assign location="$cart/myCart/books/book[0]"> <bookinfo xmlns=""> <isdn>12334455</isdn> <author>some author</author> </bookinfo> </assign>
The
exact
mappings
between
Custom
Action
Elements
and
<send>
actions
are
to
be
defined
results
in
the
individual
Custom
Action
Element
specifications.
<data id="cart"> <myCart xmlns=""> <books> <book> <bookinfo> <isdn>12334455</isdn> <author>some author</author> </bookinfo> </book> <book> <title>Freakonomics</title> </book> ... </data>
A
SCXML
1.0
processor
is
a
user
agent
that
can
parse
Here
are
examples
of
legal
and
process
Conforming
SCXML
1.0
documents.
In
a
Conforming
SCXML
1.0
Processor,
the
XML
parser
must
be
able
illegal
assignment
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.
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>
Conformance
in
SCXML
is
defined
with
respect
Now
suppose
we
assign
a
string
to
profiles.
A
Conforming
SCXML
1.0
Processor
that
supports
a
given
profile
must
support
nodeset.
The
following
assignment
statement
would
have
the
syntax
and
semantics
effect
of
all
SCXML
elements
in
that
profile
as
described
replacing
the
children
of
each
node
in
this
document.
Consequently,
a
SCXML
1.0
Processor
must
not
throw
an
error.unsupported.<element>
for
any
SCXML
element
the
nodeset
$cart/myCart/books/book
with
the
string
"The
Zen
Mind":
<assign location="$cart/myCart/books/book" expr="'The Zen Mind'"/>
results
in
that
profile
when
processing
a
Conforming
SCXML
1.0
Document.
<data id="cart"> <myCart xmlns=""> <books> <book>The Zen Mind</book> <book>The Zen Mind</book> </books> ... </data>
When
Finally
suppose
we
assign
a
Conforming
SCXML
1.0
Processor
encounters
structure
to
a
Conforming
SCXML
1.0
Document
with
non-SCXML
nodeset.
The
following
statement
would
iterate
over
the
elements
or
attributes
which
are
proprietary,
or
defined
in
a
non-SCXML
namespace,
the
nodeset
of
<book>
elements
and
which
cannot
be
processed,
replace
their
children
with
the
processor
must
ignore
them.
<price>
structure:
<assign location="$cart/myCart/books/book"> <price>20.0</price> </assign>
When
a
Conforming
SCXML
1.0
Processor
encounters
a
document
with
a
root
element
designating
a
namespace
other
than
SCXML,
its
behavior
is
undefined.
results
in
<data id="cart"> <myCart xmlns=""> <books> <book> <price>20.0</price> </book> <book> <price>20.0</price> </book> </books> ... </data>
When
a
conforming
SCXML
1.0
Processor
encounters
a
document
with
a
root
If
the
evaluation
of
any
of
the
expressions
in
an
<assign>
element
causes
an
error
to
be
raised,
evaluation
of
<scxml>
with
a
version
attribute
with
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
value
other
than
1.0,
its
behavior
is
undefined.
child
of
<book>:
<assign location="$cart/myCart/books/book[1]/ISBN" expr="'....'"/>
There
is,
however,
no
conformance
requirement
with
respect
to
performance
characteristics
of
5.9
<script>
is
not
supported
in
the
XPath
Data
Model.
If
the
SCXML
1.0
Processor.
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.
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
messages
and
how
they
map
onto
SCXML
events,
but
it
does
not
define
the
transport
mechanism,
which
is
platform-specific.
The
schema
for
the
message
is
available
at
D.9
SCXML
Message
Schema
:.
:.
The
sender
or
the
receiver
of
the
message
may
be
either
an
SCXML
session
or
an
external
entity,
but
this
specification
defines
the
behavior
for
SCXML
sessions
only
.
The contents of the individual messages are defined as follows:
The mapping between <send>, the SCXML message structure, and the event that is raised in the receiving session is given below.
<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". |
not present | 'language' attribute. | not present |
'namelist' attribute, <content> child, or <param> children | <payload> element | data field |
The sending SCXML Event I/O processor MUST populate these fields of the SCXML message structure in the manner defined above, and the receiving processor MUST use them to create the appropriate internal or external event structure as defined above.
When
an
SCXML
processor
receives
a
message
via
the
SCXML
Event
I/O
Processor
it
validates
the
syntax
of
the
incoming
message
and
checks
that
it
matches
an
active
session.
If
the
message
fails
syntactic
validation
or
does
not
match
an
active
session,
the
receiving
processor
notifies
the
sending
processor
of
the
error
and
ignores
the
message.
If
the
message
passes
validation,
but
the
receiving
processor
cannot
handle
the
data
format
contained
in
the
message,
the
receiving
processor
SHOULD
raise
the
error:
error.receive.datamismatch
error
error.communication
in
the
session
for
which
the
message
was
intended
and
MUST
ignore
the
message.
The
processor
SHOULD
also
notify
the
sending
processor
of
the
error.
It
then
ignores
the
message.
If
no
errors
occur,
the
receiving
session
converts
the
message
into
an
SCXML
event,
using
the
mapping
defined
above,
and
inserts
the
event
its
external
event
queue.
If
the
sending
entity
is
an
SCXML
session,
it
SHOULD
also
report
errors.
If
For
example,
if
the
sending
session
specifies
a
sessionid
that
does
not
exist
on
the
receiving
system,
it
SHOULD
raise
the
error:
error.send.nosuchsession.
If
the
sending
session
specifies
a
data
format
that
the
receiving
session
does
not
support,
it
SHOULD
raise
the
error:
error.send.datamismatch.
For
any
other
errors,
such
as
inability
or
is
unable
to
connect
to
the
receiving
system,
the
sending
system
it
SHOULD
raise
error.send.failed.scxmlio.
An
implementation
may
extend
any
of
the
errors
described
in
this
section
to
provide
more
information
if
it
desires.
For
example,
an
implementation
may
choose
to
raise
error.send.failed.scxmlio.cannotconnect
or
error.receive.datamismatch.ecmascript,
etc.
error
error.communication.
The
SCXML
Event
I/O
Processor
MUST
handle
the
'cancel.invoke.
invokeid
id
'
event.
In
particular,
if
SCXML
session
session1
sends
this
event
to
session
session2,
where
session1
invoked
session2
via
an
<invoke>
element
with
invokeid
invokeid
id
,
the
SCXML
Event
I/O
Processor
MUST
set
the
'continue'
variable
in
session2
to
'false'
and
discard
the
event.
(See
B
Algorithm
for
SCXML
Interpretation
for
details.)
In
all
other
cases
(that
is,
in
cases
where
the
invokeid
does
not
match),
the
SCXML
Event
I/O
processor
MUST
discard
the
event
and
SHOULD
signal
an
error.
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" hints="Email headers"/>
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" 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"> <scxml:hint>Email headers</scxml:hint> <headers xmlns="http://www.example.com/headers"> <cc>archive@example.com</cc> <subject>Example email</subject> </headers> </scxml:property> </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" hints="'Email headers'"/>
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"> <scxml:hint>Email headers</scxml:hint> <![CDATA[ headers : { cc : "audit@example.com" , subject : "Example email" } ]]> </scxml:property> </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(
D.9
SCXML
Message
Schema
).
it().
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 session.
In
profiles
supporting
both
the
Data
Module
and
the
External
Module,
the
The
access
URI
is
available
via
the
system
variable
_ioprocessors
using
the
key
"basichttp".
For
example,
in
9.2
E.2
The
ECMAScript
Profile
Data
Model
,
_ioprocessors["basichttp"]
returns
the
access
URI
(e.g.
http://www.example.com/scxml/basichttp)
for
the
basichttp
processor.
The access URI for the Basic HTTP Event I/O Processor may be sent to external components by, for example, its inclusion in the namelist attribute of the <send> element.
The access URI may also be specified in an implementation-specific manner (for example, product documentation).
Input
from
external
components
can
be
received
by
the
SCXML
implementation
at
the
basichttp
access
URI
as
HTTP
POST
requests
(see
[HTTP]
).
If
the
HTTP
parameter
'_content'
is
present,
its
value
will
be
interpreted
as
a
message
in
the
SCXML
message
format
(
D.9
SCXML
Message
Schema
).
().
Such
messages
are
mapped
to
SCXML
events
as
described
in
G
F.1
SCXML
Event
I/O
Processor
.
Implementations
MAY
accept
other
parameters
as
well.
In
such
cases,
the
mapping
of
their
values
to
SCXML
events
is
implementation-specific.
The Basic HTTP Event I/O Processor validates the message it has received, builds the appropriate SCXML event and adds it to the appropriate event queue. It then indicates 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
4.1
6.2
<send>
)
with
the
type
attribute
set
to
"basichttp".
The
target
attribute
is
set
to
the
access
URI
of
the
external
component.
The HTTP method is "POST" and parameter values are encoded by default in an application/x-www-form-urlencoded body (POST method). This default encoding MAY be overriden in a platform-specific way, e.g. by using the 'hints' attribute.
If the namelist attribute is defined, its variable names and values are mapped to HTTP parameters. If one or more <param> children are present, their names (i.e. name attributes) and values are mapped to HTTP parameters. If a <content> child is present, its value is mapped to the distinguished HTTP parameter '_content'.
If
the
external
component
returns
any
HTTP
response
code
other
than
2XX,
the
implementation
will
raise
the
error
error.send.failed.http.
error_code
error.communication
in
the
session
that
attempted
to
send
the
event,
where
error_code
is
the
HTTP
error
code
that
was
received.
event.
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
may
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
attributes
of
the
event
will
be
populated
with
values
specified
via
"namelist"
or
<param>.
"namelist"
or
<param>
items
that
do
not
correspond
to
attributes
of
the
event
will
be
ignored.
If
the
URI
specified
is
not
part
of
the
same
document,
the
error
error.send.targetunavailable
error.communication
will
be
raised.
When
a
DOM
event
is
targeted
at
the
<scxml>
root
node,
the
DOM
Event
I/O
processor
will
convert
it
into
an
SCXML
event
and
insert
it
in
the
external
event
queue.
The
attributes
of
the
DOM
event
will
be
converted
into
like-named
elements
in
the
data
field
of
the
event
(see
5.6.1
5.11.1
The
Internal
Structure
of
Events
for
details.)
DOM
events
targeted
at
other
nodes
in
the
SCXML
markup
will
be
ignored.
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="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 dataid="short_expr" expr="''" /> </transition> <transition event="DIGIT" target="int1"> <assign dataid="short_expr" expr="''" /> </transition> <transition event="POINT" target="frac1"> <assign dataid="short_expr" expr="''" /> </transition> </state> <state id="negated1"> <onentry> <assign dataid="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 dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </onentry> </state> <state id="frac1"> <onentry> <assign dataid="short_expr" expr="short_expr+'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign dataid="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 dataid="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 dataid="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> <send event="DISPLAY.UPDATE" /> </transition> <onentry> <assign dataid="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 dataid="short_expr" expr="short_expr +'.'" /> <send event="DISPLAY.UPDATE" /> </onentry> <transition event="DIGIT"> <assign dataid="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 dataid="short_expr" expr="''+ res" /> <assign dataid="long_expr" expr="''" /> <assign dataid="res" expr="0" /> </transition> <transition event="CALC.SUB"> <if cond="short_expr!=''"> <assign dataid="long_expr" expr="long_expr+'('+short_expr+')'" /> </if> <assign dataid="res" expr="eval(long_expr)" /> <assign dataid="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 dataid="long_expr" expr="long_expr+'+'" /> <elseif cond="_event.data[0]=='OPER.MINUS'" /> <assign dataid="long_expr" expr="long_expr+'-'" /> <elseif cond="_event.data[0]=='OPER.STAR'" /> <assign dataid="long_expr" expr="long_expr+'*'" /> <elseif cond="_event.data[0]=='OPER.DIV'" /> <assign dataid="long_expr" expr="long_expr+'/'" /> </if> </transition> </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>
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.