SCXML Language Reference
This document provides a comprehensive reference for the State Chart XML (SCXML) language as implemented by VSCXML. Each section links to the relevant W3C specification sections and associated conformance tests.
W3C Specification: State Chart XML (SCXML): State Machine Notation for Control Abstraction Version: W3C Recommendation 01 September 2015
Table of Contents
1. Document Structure
1.1 The <scxml> Element
The root element of every SCXML document.
W3C Spec: 3.2 <scxml> Conformance Tests: test144, test355, test576
<scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
datamodel="ecmascript"
initial="idle"
name="MyStateMachine">
<!-- states and content -->
</scxml>
Attributes
| Attribute | Required | Description |
|---|---|---|
xmlns |
Yes | Must be http://www.w3.org/2005/07/scxml |
version |
Yes | Must be 1.0 |
initial |
No | ID of initial state (or use <initial> child) |
datamodel |
No | Data model type: ecmascript, xpath, null |
name |
No | Machine name (available as _name system variable) |
binding |
No | early (default) or late - when data is initialized |
Binding Attribute
W3C Spec: 5.3 Data Binding Conformance Tests: test215, test216
- early (default): All data elements initialized when machine starts
- late: Data elements initialized when their parent state is first entered
<!-- Early binding: x initialized at startup -->
<scxml binding="early">
<state id="s1">
<datamodel>
<data id="x" expr="1"/>
</datamodel>
</state>
</scxml>
<!-- Late binding: x initialized when s1 is first entered -->
<scxml binding="late">
<state id="s1">
<datamodel>
<data id="x" expr="1"/>
</datamodel>
</state>
</scxml>
2. States
2.1 Atomic States
The simplest state type with no children.
W3C Spec: 3.3 <state> Conformance Tests: test364, test372, test570
<state id="idle">
<onentry>
<log expr="'Entered idle state'"/>
</onentry>
<onexit>
<log expr="'Exiting idle state'"/>
</onexit>
<transition event="start" target="running"/>
</state>
Attributes
| Attribute | Description |
|---|---|
id |
Unique identifier for the state |
initial |
Initial child state (for compound states) |
2.2 Compound (Hierarchical) States
States containing child states, creating a hierarchy.
W3C Spec: 3.3 <state> Conformance Tests: test403, test404, test405, test409
<state id="playing" initial="normal">
<!-- Parent transitions apply to ALL children -->
<transition event="stop" target="stopped"/>
<state id="normal">
<transition event="fastforward" target="fast"/>
</state>
<state id="fast">
<transition event="normal" target="normal"/>
</state>
</state>
Key behaviors:
- Child states inherit parent transitions
- Entering a compound state automatically enters its initial child
- Exiting a compound state exits all descendant states
2.3 Parallel States
Multiple regions that are active simultaneously.
W3C Spec: 3.4 <parallel> Conformance Tests: test204, test205, test206, test207, test210, test410, test411, test412
<parallel id="operating">
<!-- Region 1: Temperature control -->
<state id="temperature" initial="normal">
<state id="normal">
<transition event="overheat" target="cooling"/>
</state>
<state id="cooling">
<transition event="cooled" target="normal"/>
</state>
</state>
<!-- Region 2: Pressure control -->
<state id="pressure" initial="stable">
<state id="stable">
<transition event="pressure_high" target="venting"/>
</state>
<state id="venting">
<transition event="pressure_normal" target="stable"/>
</state>
</state>
</parallel>
Key behaviors:
- All child regions are active simultaneously
- Each region has its own active state
- Events are processed by all regions
- Exiting a parallel state exits all regions
2.4 Final States
Indicate completion of a compound state.
W3C Spec: 3.7 <final> Conformance Tests: test372, test570, test571
<state id="process" initial="step1">
<state id="step1">
<transition event="done" target="step2"/>
</state>
<state id="step2">
<transition event="done" target="complete"/>
</state>
<final id="complete">
<donedata>
<param name="result" expr="computedValue"/>
</donedata>
</final>
</state>
When a <final> state is entered:
- A
done.state.{parent-id}event is generated - If the final state has
<donedata>, it's included in the event - The parent compound state is considered "final"
Interactive Example: See Done Events & Donedata for a multi-phase workflow demonstrating
done.state.*events with structured data passing.
2.5 Initial Element
Explicitly specify the initial state with executable content.
W3C Spec: 3.6 <initial> Conformance Tests: test364, test333
<state id="form">
<initial>
<transition target="step1">
<log expr="'Starting form wizard'"/>
</transition>
</initial>
<state id="step1"/>
<state id="step2"/>
</state>
The <initial> element allows:
- Running executable content when entering the compound state
- Dynamically choosing the initial state via conditions
2.6 History States
Remember and restore previous state configuration.
W3C Spec: 3.8 <history> Conformance Tests: test387, test388, test579, test580
Shallow History
Remembers only the immediate child that was active.
<state id="editor" initial="editing">
<history id="editor_history" type="shallow">
<transition target="editing"/> <!-- Default if no history -->
</history>
<state id="editing">
<state id="insert_mode"/>
<state id="command_mode"/>
</state>
<state id="preview"/>
<transition event="suspend" target="suspended"/>
</state>
<state id="suspended">
<transition event="resume" target="editor_history"/>
</state>
Deep History
Remembers the full descendant state configuration.
<state id="editor">
<history id="editor_deep_history" type="deep">
<transition target="editing"/>
</history>
<state id="editing" initial="insert_mode">
<state id="insert_mode"/>
<state id="command_mode"/>
</state>
<state id="preview"/>
</state>
| Type | Behavior |
|---|---|
shallow |
Restores only the direct child state |
deep |
Restores the entire descendant state configuration |
Interactive Example: See Deep vs Shallow History for a hands-on demonstration with a text editor suspend/resume scenario.
3. Transitions
3.1 Basic Transitions
W3C Spec: 3.5 <transition> Conformance Tests: test403, test404, test405, test406, test407, test409
<transition event="submit" target="processing" cond="isValid">
<log expr="'Form submitted'"/>
</transition>
Attributes
| Attribute | Description |
|---|---|
event |
Event name(s) that trigger this transition (space-separated) |
target |
Target state ID(s) (space-separated for parallel targets) |
cond |
Guard condition (boolean expression) |
type |
external (default) or internal |
3.2 Event Matching
W3C Spec: 3.12.1 Event Descriptors Conformance Tests: test375, test376, test377, test378
Events match using prefix matching with dots as delimiters:
<!-- Matches: error, error.parse, error.parse.xml -->
<transition event="error"/>
<!-- Matches only: error.parse and error.parse.* -->
<transition event="error.parse"/>
<!-- Matches ANY event -->
<transition event="*"/>
<!-- Multiple events (space-separated) -->
<transition event="submit cancel timeout"/>
3.3 Guard Conditions
W3C Spec: 3.5 <transition> Conformance Tests: test322, test324, test325, test326, test329
<!-- Simple condition -->
<transition event="submit" cond="count > 0" target="processing"/>
<!-- Complex conditions -->
<transition event="login" cond="attempts < maxAttempts" target="authenticating"/>
<transition event="login" cond="attempts >= maxAttempts" target="locked"/>
<!-- XML entities required -->
<!-- < for < -->
<!-- > for > -->
<!-- & for & -->
Guards are evaluated in document order. The first transition with a true guard is taken.
3.4 Transition Types
W3C Spec: 3.5 <transition> Conformance Tests: test0412
External Transitions (default)
Exit and re-enter states, even when targeting a descendant.
<state id="parent">
<onentry><log expr="'entered parent'"/></onentry>
<onexit><log expr="'exited parent'"/></onexit>
<!-- External: exits parent, enters child -->
<transition event="go" target="child"/>
<state id="child"/>
</state>
Internal Transitions
Don't exit the source state when transitioning to a descendant.
<state id="parent">
<onentry><log expr="'entered parent'"/></onentry>
<!-- Internal: does NOT exit parent -->
<transition event="go" target="child" type="internal"/>
<state id="child"/>
</state>
3.5 Targetless Transitions
Execute actions without changing state.
W3C Spec: 3.5 <transition> Conformance Tests: test505, test506
<state id="counter">
<!-- Targetless: stays in same state, just executes actions -->
<transition event="increment">
<assign location="count" expr="count + 1"/>
</transition>
</state>
3.6 Eventless (Always) Transitions
Transitions without an event attribute are taken automatically.
W3C Spec: 3.5 <transition> Conformance Tests: test148, test149
<state id="checking">
<!-- Taken automatically when condition is true -->
<transition cond="isReady" target="processing"/>
<!-- Fallback if not ready -->
<transition target="waiting"/>
</state>
4. Executable Content
4.1 Entry and Exit Actions
W3C Spec: 4.2 <onentry> and 4.3 <onexit> Conformance Tests: test375, test376
<state id="active">
<onentry>
<log expr="'Entering active state'"/>
<assign location="entryTime" expr="Date.now()"/>
</onentry>
<onexit>
<log expr="'Exiting active state'"/>
<assign location="duration" expr="Date.now() - entryTime"/>
</onexit>
</state>
Execution order:
- Exit actions run in reverse document order (deepest first)
- Transition actions run
- Entry actions run in document order (parent first)
4.2 Assign
Modify datamodel variables.
W3C Spec: 4.6 <assign> Conformance Tests: test286, test287, test288
<!-- Simple assignment -->
<assign location="count" expr="count + 1"/>
<!-- Object property -->
<assign location="user.name" expr="'Alice'"/>
<!-- Array element -->
<assign location="items[0]" expr="newItem"/>
<!-- Complex expression -->
<assign location="total" expr="items.reduce((sum, i) => sum + i.price, 0)"/>
4.3 Log
Output debug information.
W3C Spec: 4.8 <log> Conformance Tests: test557
<!-- Simple message -->
<log expr="'Processing started'"/>
<!-- With label -->
<log label="Debug" expr="'Current count: ' + count"/>
<!-- Formatted output -->
<log label="Status" expr="'User ' + username + ' logged in at ' + timestamp"/>
4.4 Raise
Queue an internal event for immediate processing.
W3C Spec: 4.4 <raise> Conformance Tests: test560, test161, test162
<state id="processing">
<onentry>
<raise event="internal.start"/>
</onentry>
<transition event="internal.start">
<!-- Process immediately in same macrostep -->
</transition>
</state>
Internal events (from raise) are processed before external events.
4.5 Send
Queue an event for later processing, optionally with a delay.
W3C Spec: 4.5 <send> Conformance Tests: test201, test500, test501, test509, test510, test513, test521
<!-- Send to self (default) -->
<send event="timeout" delay="5s"/>
<!-- With event data -->
<send event="response">
<param name="status" expr="200"/>
<param name="message" expr="'OK'"/>
</send>
<!-- With content -->
<send event="data">
<content expr="JSON.stringify(payload)"/>
</send>
<!-- Named send for cancellation -->
<send event="timeout" delay="10s" id="timeout_timer"/>
Attributes
| Attribute | Description |
|---|---|
event |
Event name to send |
target |
Destination (#_internal, #_parent, #_sessionid, or invoke ID) |
type |
I/O processor type (default: SCXML event processor) |
delay |
Time delay (e.g., 5s, 500ms) |
id |
ID for later cancellation with <cancel> |
idlocation |
Variable to store generated ID |
4.6 Cancel
Cancel a delayed event.
W3C Spec: 4.7 <cancel> Conformance Tests: test208, test210
<state id="waiting">
<onentry>
<send event="timeout" delay="30s" id="wait_timer"/>
</onentry>
<onexit>
<!-- Cancel timer when leaving state -->
<cancel sendid="wait_timer"/>
</onexit>
<transition event="response" target="processing"/>
<transition event="timeout" target="error"/>
</state>
4.7 If / Elseif / Else
Conditional execution of actions.
W3C Spec: 4.9 <if> Conformance Tests: test147
<if cond="score >= 90">
<assign location="grade" expr="'A'"/>
<elseif cond="score >= 80"/>
<assign location="grade" expr="'B'"/>
<elseif cond="score >= 70"/>
<assign location="grade" expr="'C'"/>
<else/>
<assign location="grade" expr="'F'"/>
</if>
4.8 Foreach
Iterate over arrays.
W3C Spec: 4.10 <foreach> Conformance Tests: test152, test153, test525
<foreach array="items" item="item" index="i">
<log expr="'Item ' + i + ': ' + item.name"/>
<if cond="item.selected">
<assign location="selectedCount" expr="selectedCount + 1"/>
</if>
</foreach>
| Attribute | Required | Description |
|---|---|---|
array |
Yes | Array expression to iterate |
item |
Yes | Variable name for current element |
index |
No | Variable name for current index |
4.9 Script
Execute arbitrary code.
W3C Spec: 4.11 <script> Conformance Tests: test301, test302, test303, test304
<script>
// Complex logic
var result = items.filter(function(item) {
return item.price > 100;
}).map(function(item) {
return item.name;
});
// Modify datamodel
filteredNames = result;
totalCount = result.length;
</script>
Note: For ECMAScript datamodel, use standard JavaScript syntax.
5. Data Model
5.1 Datamodel Element
Container for data declarations.
W3C Spec: 5.2 <datamodel> Conformance Tests: test276
<scxml datamodel="ecmascript">
<datamodel>
<data id="count" expr="0"/>
<data id="items" expr="[]"/>
<data id="config" expr="{ debug: true, maxRetries: 3 }"/>
</datamodel>
<!-- State-scoped data -->
<state id="processing">
<datamodel>
<data id="localVar" expr="'initial'"/>
</datamodel>
</state>
</scxml>
5.2 Data Element
Declare a single variable.
W3C Spec: 5.3 <data> Conformance Tests: test276, test277, test278, test279, test550, test551
<!-- Simple values -->
<data id="count" expr="0"/>
<data id="name" expr="'Alice'"/>
<data id="flag" expr="true"/>
<!-- Complex values -->
<data id="items" expr="[1, 2, 3]"/>
<data id="user" expr="{ name: 'Bob', age: 30 }"/>
<!-- From external source (XPath datamodel) -->
<data id="config" src="config.xml"/>
5.3 The In() Predicate
Test if a state is currently active.
W3C Spec: 5.10 In() Conformance Tests: test127
<transition cond="In('processing')" event="abort" target="cancelled"/>
<if cond="In('authenticated')">
<send event="refresh_token"/>
</if>
5.4 Donedata
Return data when a final state is reached.
W3C Spec: 4.12 <donedata> Conformance Tests: test372, test570
<final id="success">
<donedata>
<param name="result" expr="computedResult"/>
<param name="duration" expr="endTime - startTime"/>
</donedata>
</final>
The data is accessible via _event.data when handling done.state.{parentId}.
6. Events
6.1 Event Structure
W3C Spec: 5.11 Event Objects Conformance Tests: test326, test329
<transition event="response">
<log expr="'Event name: ' + _event.name"/>
<log expr="'Event data: ' + JSON.stringify(_event.data)"/>
<log expr="'Event type: ' + _event.type"/>
<log expr="'Origin: ' + _event.origin"/>
</transition>
Event Properties
| Property | Description |
|---|---|
name |
The event name (e.g., "submit") |
type |
internal, external, or platform |
data |
Event payload (from <param> or <content>) |
origin |
Source of the event |
origintype |
Type of the source |
sendid |
ID from the <send> element |
invokeid |
ID if from an invoked child |
6.2 Internal vs External Events
W3C Spec: 5.11.1 Internal Events Conformance Tests: test560, test161
- Internal events: Generated by
<raise>, processed immediately in the current macrostep - External events: Generated by
<send>, queued for later processing
<state id="processing">
<onentry>
<!-- Internal: processed immediately -->
<raise event="internal.check"/>
<!-- External: queued for later -->
<send event="external.check"/>
</onentry>
<!-- This runs first (internal event) -->
<transition event="internal.check">
<log expr="'Internal check'"/>
</transition>
<!-- This runs after all internal events -->
<transition event="external.check">
<log expr="'External check'"/>
</transition>
</state>
6.3 Special Events
W3C Spec: 4.5 <send>
Done Events
Generated when a <final> state is entered:
| Event | When Generated |
|---|---|
done.state.{id} |
When a compound state's final child is entered |
done.invoke.{id} |
When an invoked child machine reaches final |
<state id="parent">
<state id="processing" initial="step1">
<state id="step1">
<transition target="done"/>
</state>
<final id="done"/>
</state>
<!-- Triggered when 'done' final state is entered -->
<transition event="done.state.processing" target="complete"/>
</state>
Error Events
Generated when errors occur:
| Event | Description |
|---|---|
error.execution |
Script or expression error |
error.communication |
Send failed |
error.platform |
Platform-specific error |
<transition event="error">
<log label="Error" expr="'Error: ' + _event.name"/>
</transition>
Interactive Example: See Error Handling & Retry Patterns for production-ready error recovery with automatic retry logic, exponential backoff, and circuit breaker patterns.
7. Invoke
Spawn child state machines.
W3C Spec: 6.4 <invoke> Conformance Tests: test215, test216, test220, test223, test224, test225, test226, test228, test229, test230, test232, test233, test234, test235, test236, test237, test239, test240, test241, test242, test243, test244, test245, test247, test250, test252, test253
7.1 Basic Invoke
<state id="parent">
<invoke src="child.scxml" id="myChild">
<param name="input" expr="parentData"/>
</invoke>
<!-- Handle child completion -->
<transition event="done.invoke.myChild" target="complete"/>
</state>
7.2 Invoke Attributes
| Attribute | Description |
|---|---|
src |
URL of the SCXML document to invoke |
srcexpr |
Expression evaluating to the URL |
type |
Service type (default: http://www.w3.org/TR/scxml/) |
id |
Identifier for this invocation |
idlocation |
Variable to store generated ID |
autoforward |
Forward events to child (true/false) |
7.3 Parent-Child Communication
Parent to Child
<!-- Parent sends to child -->
<send event="update" target="#_myChild">
<param name="value" expr="newValue"/>
</send>
Child to Parent
<!-- Child sends to parent -->
<send event="status_update" target="#_parent">
<param name="progress" expr="currentProgress"/>
</send>
7.4 Finalize
Process data when child completes.
W3C Spec: 6.5 <finalize> Conformance Tests: test252, test253
<invoke src="calculator.scxml" id="calc">
<param name="a" expr="10"/>
<param name="b" expr="20"/>
<finalize>
<assign location="result" expr="_event.data.result"/>
</finalize>
</invoke>
7.5 Auto-forward
Automatically forward events to child.
<invoke src="processor.scxml" id="proc" autoforward="true"/>
<!-- Events like "cancel" will be forwarded to the child -->
<transition event="cancel">
<log expr="'Cancelled - child also receives this'"/>
</transition>
8. System Variables
W3C Spec: 5.11 System Variables Conformance Tests: test312, test313, test314, test318, test319, test321, test322, test324
8.1 _event
The current event being processed.
<transition event="submit">
<log expr="'Event: ' + _event.name"/>
<log expr="'Data: ' + JSON.stringify(_event.data)"/>
</transition>
8.2 _sessionid
Unique identifier for this state machine instance.
<onentry>
<log expr="'Session ID: ' + _sessionid"/>
</onentry>
8.3 _name
The name of the state machine (from <scxml name="...").
<onentry>
<log expr="'Machine name: ' + _name"/>
</onentry>
8.4 _ioprocessors
Available I/O processors.
<onentry>
<log expr="'I/O Processors: ' + JSON.stringify(_ioprocessors)"/>
</onentry>
8.5 _x
Platform-specific system data.
<onentry>
<log expr="'Platform data: ' + JSON.stringify(_x)"/>
</onentry>
Quick Reference
State Types
| Element | Description |
|---|---|
<state> |
Atomic or compound state |
<parallel> |
Concurrent regions |
<final> |
Completion state |
<history> |
Remember previous state |
<initial> |
Initial transition |
Executable Content
| Element | Description |
|---|---|
<onentry> |
Entry actions |
<onexit> |
Exit actions |
<transition> |
State transition with optional actions |
<assign> |
Variable assignment |
<log> |
Debug output |
<raise> |
Internal event |
<send> |
External/delayed event |
<cancel> |
Cancel delayed event |
<if>/<elseif>/<else> |
Conditional execution |
<foreach> |
Loop over array |
<script> |
Arbitrary code |
Data Elements
| Element | Description |
|---|---|
<datamodel> |
Container for data |
<data> |
Variable declaration |
<donedata> |
Final state return data |
<param> |
Parameter (for send/invoke) |
<content> |
Content (for send/invoke) |
See Also
- Introduction to State Machines - Conceptual overview with examples
- Data Models - ECMAScript, XPath, and Native datamodel details
- Invoke Tutorial - Parent-child communication
- W3C SCXML Specification - Official standard
Interactive Examples
- Deep vs Shallow History - History states with suspend/resume patterns
- Error Handling & Retry - Error events, retry logic, circuit breakers
- Done Events & Donedata - Multi-phase workflows with completion data