SCXML Format

Overview

From Wikipedia :

SCXML stands for State Chart XML: State Machine Notation for Control Abstraction. It is an XML-based markup language that provides a generic state-machine-based execution environment based on Harel statecharts.

SCXML is able to describe complex finite state machines. For example, it is possible to describe notations such as sub-states, parallel states, synchronization, or concurrency, in SCXML.

SCXML format specification can be found on W3 official website.

SCXML format was designed to describe both structure and functionality inside a single file. But since we are using it only to define structure, some of SCXML features will be ignored.

Supported SCXML tags and attributes

Tag

Attribute

Status

Core Constructs

scxml

initial

✅ supported

name

❌ ignored

xmlns

✅ supported

version

❌ ignored

datamodel

❌ ignored

binding

❌ ignored

state

id

✅ supported

initial

✅ supported

src

➕ custom

parallel

id

✅ supported

transition

event

✅ supported

cond

✅ supported

target

✅ supported

type

✅ supported

initial

✅ supported

final

id

✅ supported

onentry

✅ supported

onexit

✅ supported

history

id

✅ supported

type

✅ supported

Executable Content

raise

❌ ignored

if

❌ ignored

elseif

❌ ignored

else

❌ ignored

foreach

❌ ignored

log

❌ ignored

Data Model and Data Manipulation

datamodel

❌ ignored

data

❌ ignored

assign

❌ ignored

donedata

❌ ignored

content

❌ ignored

param

❌ ignored

script

➕ custom

External Communications

send

❌ ignored

cancel

❌ ignored

invoke

type

❌ ignored

typeexpr

❌ ignored

src

➕ custom

srcexpr

➕ custom

id

❌ ignored

idlocation

❌ ignored

namelist

❌ ignored

autoforwad

❌ ignored

finalize

❌ ignored

Extensions

xi:include

✅ supported

Callbacks Definition

There are 5 types of callbacks that could be defined for HSM:

  • on state changed:

<state id="state_1">
    <invoke srcexpr="onState1"/>
</state>
  • on state entering:

<state id="state_1">
    <onentry>
        <script>onEnteringState1</script>
    </onentry>
</state>
  • on state exiting:

<state id="state_1">
    <onexit>
        <script>onExitingState1</script>
    </onexit>
</state>
  • on transition:

<state id="state_1">
    <transition event="NEXT_STATE" target="state_2">
        <script>onNextStateTransition</script>
    </transition>
</state>
  • on condition check:

<state id="state_1">
    <transition event="NEXT_STATE" cond="checkNextStateTransition" target="state_2"/>
</state>

Callback names should comply with C++ identifier naming rules.

Splitting SCXML files

When defining your HSM structure you might want to reuse a state or a group of states for some common logic (for example error handling). Included file must comply with SCXML format and have a root node <scxml> defined.

There are two ways to include another file inside of your scxml:

  • using <xi:include> tag

  • using “src” attribute of a state

Include using <xi:include>

This is a standard way which is compliant with W3 specification. For this tag to work additional namespace must be added to your scxml:

<scxml xmlns:xi="http://www.w3.org/2001/XInclude">

Restrictions and things to consider:

  • <xi:include> tag can only be a child of <scxml> or <state> nodes. It’s not allowed to put it anywhere else.

  • availability of initial state in included file is optional, but your HSM will usually not work without one (validation was disabled on purpose to allow importing of a single state).

  • it’s highly recommended to wrap <xi:include> into a <state> node which doesnt contain any other states or includes (transitions are allowed).

    • in this case parent state will work like a namespace altering included state names to avoid name collision (if you want to include same file multiple times);

    • exit transition can be defined

  • when using <xi:include> on the same level with other states or include keep in mid that:

    • code will be inserted as-is. name collisions, incorrect initial states, non existent transitions will not be resolved;

    • GUI editors don’t allow to define exit/enter transitions (though it’s possible to define them manually in XML you will loose ability to edit such file in GUI editor).

Using <xi:include> with a wrapper state

/examples/scxml/includes/xi_include_wrapped.scxml

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:xi="http://www.w3.org/2001/XInclude">
    <state id="State0">
        <transition event="EVENT_1" target="ImportedState"></transition>
    </state>
    <state id="ImportedState">
        <transition event="EVENT_2" target="State2"></transition>
        <xi:include href="./substates1.scxml" parse="xml"></xi:include>
    </state>
    <state id="State2"></state>
</scxml>

/examples/scxml/includes/substates1.scxml

<scxml initial="state_a" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
    <state id="state_a">
        <transition event="EVENT_B" target="state_b"></transition>
    </state>
    <state id="state_b">
        <transition event="EVENT_C" target="state_c"></transition>
    </state>
    <state id="state_c">
        <transition event="EVENT_B" target="state_b"></transition>
    </state>
</scxml>

Result structure

Example of wrapped xi:include

Including <xi:include> directly

/examples/scxml/includes/xi_include_direct.scxml

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:xi="http://www.w3.org/2001/XInclude">
    <state id="State0">
        <transition event="EVENT_1" target="State1"></transition>
    </state>
    <xi:include href="state1.scxml" parse="xml"></xi:include>
    <state id="State2"></state>
</scxml>

Note how we define a transition to State1 even though it’s not defined in xi_include_direct.scxml. Transition will become valid after code from state1.scxml will be included.

<transition event="EVENT_1" target="State1"></transition>

/examples/scxml/includes/state1.scxml

<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
    <state id="State1">
        <onentry>
            <script>onEnteringState1</script>
        </onentry>
        <onexit>
            <script>onExitingState1</script>
        </onexit>
        <transition event="SELF_TRANSITION"></transition>
        <transition event="EVENT_2" target="State2"></transition>
        <invoke srcexpr="onState1"></invoke>
    </state>
</scxml>

Note how we define a transition to State2 even though it’s not defined in state1.scxml:

<transition event="EVENT_2" target="State2"></transition>

Result structure

Example of direct usage of xi:include

Include using “src” attribute of <state>

It’s possible to reference external scxml files by using “src” attribute of a <state>.

<state id="..." src="file path">
    ...
</state>

This will behave exactly same as a <xi:include> tag wrapped inside a <state>.

Keep in mind that this is not a part of W3 SCXML specification and was added only because it’s supported by scxmlgui.

/examples/scxml/includes/state_src_include.scxml

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
 <state id="State0">
  <transition event="EVENT_1" target="Substates1"></transition>
 </state>
 <state id="State2"></state>
 <state id="Substates1" src="./substates1.scxml">
  <transition event="EVENT_2" target="State2"></transition>
 </state>
</scxml>

Result structure

Example of using state::src