-
Notifications
You must be signed in to change notification settings - Fork 14
Examples
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
This is a standard way which is compliant with W3 specification. For this tag to work additional namespace must be added to your 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).
<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>
<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
NOTE: SCXML files were edited manually 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>
<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
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.
<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