Table of Contents
XMLScript
Warning
- Do not replace standard Rocrail functions with XMLScript.
- Do not try to mangle the automatic Rocrail engine.
- The scripts are executed asynchrone, and needs multithreading programming know how.
- If encountering unexpected behaviour: Turn off XMLScript actions.
- If uncertain: Do not use XMLScript, or ask for help in the Forum.
- Do not use the same variables in multiple XMLScripts, which will be set to new values, to avoid unexpected results including Server crashes.
Introduction
Check basic Rocrail functionality before inventing the wheel again with XMLScript.
XMLScript can be used in combination with run ext. program action.
Its primary goal is to simplify and to reduce the number of actions and conditions.
The XML used for XMLScript is the same as used in the Rocrail plan.xml.
Requirements
- UTF-8 Editor, for example Notepad++ or Gedit or the internal xml-editor of rocview to edit an XML file on the server as described below on this page.
- Windows Notepad editor is not supported.
- Some programming and XML knowledge.
Recommendation
- Keep the XMLScript short and without long sleeps and long loops; It will block the calling object from processing events and commands if it is not defined as Asynchrone.
- Do not try to outsmart the automatic mode; Post a feature request in the forum instead if something basic is missing.
- Object IDs with blanks are not supported; Use underscores instead.
- Variable/function names may not contain operation characters like "+-*<>^!=?%/".
Setup
Blanks in path or filename are not supported!
- Create a XMLScript and save it in a file. (See: Simple Example)
- Create a "run ext. program" action.
- Select the XMLScript file. (If the script file is in the workspace directory a path is not necessary.)
- Ready to use this action on any Rocrail object.
Simple Example
Switch on the track power and start the automatic mode:
<xmlscript> <sys cmd="go"/> <auto cmd="on"/> </xmlscript>
Edit on the Server
To create and edit an XMLScript on the Server the Action Dialog can be used:
If the XMLScript does not already exist on the Server a XMLScript skeleton will be created:
<?xml version="1.0" encoding="UTF-8"?> <xmlscript> </xmlscript>
The XMLScript editor can also be opened by a double click on the Index.
If "<xmlscript>" is amended with the description "<desc="xxx">" (e. g. script name), the description will be displayed in the trace. E. g.
<?xml version="1.0" encoding="UTF-8"?> <xmlscript desc="My_Script.xml"> </xmlscript>
Validate
Check if the XML is "Well Formed". 1)
Insert
Insert the selected statement or command at the cursor position.
The [\n] checkboxes control the line feeds before and after the statement.
macOS
To use this editor the "Use smart quotes and dashes" option must be disabled to avoid creating invalid XML:
System preferences → Language & Region → Keyboard preferences → Text
With this option enabled, which is by default, it will automatically convert double hyphens (--), used in XML comments, into em dashes (—),
and ("straight") quotation marks into typographical (“curly”) ones.
This will make the XMLScript invalid.
Calling Parameters
Calling parameters can be accessed by variables with the naming of "%param1%…%paramN%".
See: ActionControl Parameter
Snippet:
<xmlscript> <if condition="%frombkid% # %param1%"> <then> </then> </if> </xmlscript>
Statements
foreach
The foreach loop is used for "do this to everything in this table" with optional a condition and/or state.
The loop can be stopped with a break or exit statement.
If the condition and/or state does not match it skips to the next object in this table.
<xmlscript> <foreach table="lclist" condition="#var2%oid% < &time|#var1 < &time" alltrue="true"> <fn fnchanged="3" f3="true"/> <vr id="var2%oid%" text="empty"/> <vr id="var2%oid%" value="0"/> <lc cmd="go"/> <sleep time="10"/> </foreach> </xmlscript>
This script will iterate the loco table and will switch function 3 on and give the go command for every loco.
The oid, the ID of the current Object in the list, value is automatically generated in the loop.
In case the table is lclist the short ID can also be used: %soid%".2)
<xmlscript> <foreach table="lclist" condition="%lcclass% # BA"> <lc cmd="go"/> </foreach> </xmlscript>
This foreach starts every loco with the class BA.
<xmlscript> <foreach table="lclist" state="co Test = on"> <if state="lc %oid% = Block3|lc %oid% = Block2|lc %oid% = Block1" alltrue="false"> <then> <lc cmd="go"/> </then> </if> </foreach> </xmlscript>
Start every loco which resides in block 'Block3', 'Block2' or 'Block1'.
while
The while statement is a loop and can check condition, states and class. At least one of them should be defined otherwise the while loop will not be executed.
As long as the statement is true the commands in the while will be executed.
<xmlscript> <vr id="var1" value="0"/> <while condition="#var1 < 10" max="10"> <vr id="var1" value="#var1 + 1"/> <continue condition="#var1 = 4" cmt="var1 is 4"/> <sys cmd="go"/> </while> </xmlscript>
If the while loop is endless it will be stopped by the max attribute which is default 10.
Higher max values than 100 will be truncated to 100 to avoid server blocking and crashing automatically running locomotives.
if
The if statement is used for flow control and can check condition, states and class.
If the statement is true the commands in the then will be executed, if its not true the else commands will be executed.
The else is optional.
<xmlscript> <if condition="#var1 < &time" state="sg sem3 = green" class="bk 4711 = AB" alltrue="true" connect="and"> <then> <lc id="@loco" cmd="go"/> <tx id="booster1" format="var1 is #var1"/> </then> <else> <lc id="@loco" cmd="stop"/> <lc id="@loco" cmd="classset" class="AB"/> <bk id="4711" cmd="classdel" class="AB"/> <bk id="4711" cmd="classadd" class="CD"/> </else> </if> </xmlscript>
The text value of the variable loco contains the loco ID.
If the loco ID does not exist a block will be searched by that ID and in case it exist the loco ID in the block will be used.
Both condition and state may be used in the if statement. At least one of them must be specified.
<xmlscript> <if state="st b1-b2 = locked|st b2-b3 = locked" alltrue="false"> <then> <tx id="tx1" format="route is locked"/> </then> <else> <tx id="tx1" format="route not locked"/> </else> </if> </xmlscript>
Text tx1 is set to "route is locked" if Route "b1-b2" OR Route "b2-b3" is in state locked.
If this Routes are not in state locked, tx1 is set to "route not locked".
switch
The integer value of the switch var is used to select the case with the same value.
If no match was found the default will be used in case its defined.
Number example
<xmlscript> <switch var="#var1"> <case val="0"> <sys cmd="go"/> </case> <case val="1"> <auto cmd="on"/> </case> <default> <sys cmd="stop"/> </default> </switch> </xmlscript>
Multiple case values are deprecated, and are strongly discourage to use.
A case may have multiple integer values in the following format:
<case val="0|1|5|8">
One of the values must match.
String example
<xmlscript> <switch var="%callerid%"> <case val="loco1"> <sys cmd="go"/> </case> <case val="but1"> <sys cmd="reset"/> </case> </switch> </xmlscript>
Note: A switch statement has nothing todo with a Rocrail Switch-Object.
call
Functions must be declared in the first level of the XMLScript and must have set an ID.
Call the function with the wanted ID: <call id="doeIets"/>
Multiple functions are allowed.
Parameters can be accessed by %subparam1%…%subparamN%.
<xmlscript> <function id="doeIets"> <tx id="tx1" format="function doeIets"/> </function> <switch var="#var1"> <case val="0"> <sys cmd="go"/> </case> <default> <sys cmd="stop"/> <call id="doeIets" param="test1,test2"/> </default> </switch> </xmlscript>
Restrictions
- Calls in functions are not supported.
exit
Exit the XMLScript. The cmt="reason" can be used for tracing
<xmlscript> <if condition=""> <then> <exit cmt="Test."/> </then> </if> </xmlscript>
break
Ends a foreach and while loop with or without condition. The cmt="reason" can be used for tracing.
This statement has no effect if its not within a foreach loop.
<xmlscript> <foreach table="lclist"> <if condition=""> <then> <break cmt="Test."/> </then> </if> </foreach> </xmlscript>
trace
XMLScript traces will be in green color in Rocview.
<xmlscript> <trace text="Hi there! I'm %callerid%. :)"/> </xmlscript>
sleep
A sleep time in ms.
<xmlscript> <foreach table="lclist"> <if condition=""> <then> <sleep time="100"/> </then> </if> </foreach> </xmlscript>
sub
Call another XMLScript with file="script.xml" and function id="functionName"
<xmlscript> <sub file="lib1.xml" id="doeIets" param="test1,test2"/> </xmlscript>
If the function ID is set to underscore, id="_", then the whole XMLScript will be executed excluding function definitions.3)
If no function ID is set the %oid% will be used to find a fitting function.
Parameters can be accessed by %subparam1%…%subparamN%.
Library example lib1.xml:
<xmlscript> <function id="doeIets"> <sys cmd="stop"/> </function> </xmlscript>
The function ID must be used to call functions from a XMLScript library file.
Most helpfull if more then one XMLScript share common functions.
query
With the query statement a variable can be used to get the attribute text and integer value of a certain object.
A query does only provide object properties and no run time information.
<query vr="var1" table="waybilllist" id="%oid%" get="cartype"/>
After the query the variable can be use for comparing text and/or numbers. Normal text will have a zero value result.
To get a value from a sub node:
<query vr="var1" table="sclist" id="%oid%" sub="scentry" subidx="3" get="text"/>
Instead of the subidx the subid can also be used if the sub node has an ID.
Query variables must be XMLScript unique to avoid unexpected results. |
Function example
The loco ID, locid, is retrieved from block cb4 in variable lcid.
The function command requires a loco ID, which is provided by the text contents of the variable @lcid.
<xmlscript> <query vr="lcid" table="bklist" id="cb4" get="locid"/> <fn id="@lcid" fnchanged="3" f3="true"/> </xmlscript>
set
With the set statement a variable can be used to set the attribute text or integer value, depending of setint, of a certain object.
<set vr="var1" table="waybilllist" id="%oid%" set="cartype" setint="false"/>
To set a value of a sub node:
<set vr="var1" table="sclist" id="%oid%" sub="scentry" subidx="3" set="text" setint="false"/>
Instead of the subidx the subid can also be used if the sub node has an ID.
clock
15401+ |
With the clock get command:
<clock cmd="get"/>
three variables will be updated.
Variable name | Value | Text |
---|---|---|
modeltime | hour * 3600 + minute * 60 + seconds | hh:mm.ss |
realtime | hour * 3600 + minute * 60 + seconds | hh:mm.ss |
systemtick | count of 10ms since Rocrail server start | - |
The systemtick will overflow at 4294967295(119.3 hours) on 32bit and 18446744073709551615 on 64bit systems.
Condition format
value | comparator | value |
Additional conditions must be separated with a pipe character without any extra blank:
condition="#var2%oid% < &time|#var1 < &time"
See for possible variables: Text variables
System variables | |
---|---|
&time | Model time in seconds |
Comparators | |
---|---|
= | equal number |
! | not equal number |
# | equal text |
- | not equal text |
> | greater than number |
< | smaller than number |
~ | contains text (@var_1 ~ @var_2 is true, when text of var_1 contains complete text of var_2) - since version 2.1.1010 |
alltrue
Alltrue is default true if its not set.
If alltrue is set to false only one of the conditions, one of the states and one of the classes must be true.
connect
In case the if statements contains conditions, states and or classes, those are connected by default with and.
If only one of the must be true, the connect attribute can be set to or.
State/Class format
Object type | Object ID without blanks | Comparator | State/Class value |
The values must be separated with blanks.
Additional states must be separated with a pipe character without any extra blank:
state="st b1-b2 = locked|st b2-b3 ! locked"
Object IDs with blanks are not supported; Use underscores or dots instead.
Comparators | |
---|---|
= | equal state |
! | not equal state |
State Objects
Object Name | Object type | State values | Remark |
---|---|---|---|
Signal | sg | red, green, yellow, white, blank, aspect number | |
Switch | sw | left, right, straight, turnout, locked, free, unlocked | |
Sensor | fb | true, false, on, off | true = on, false = off |
Output | co | on, off, active | |
Location | location | free | The 'free' state will check if the loco is allowed and if a location block is free. |
Block | bk | free, occupied, closed, open, reserved | |
Turntable | tt | free, occupied, closed, open, reserved, #, pending | The # represents the current bridge position. If state pending is true the bridge is moving. |
Route | st | free, locked, unlocked, closed | |
System | sys | go, stop | |
Automode | auto | on, off | |
Locomotive | lc | fwd, rev, +, -, min, mid, cruise, max, block, "blockID", steam, diesel, electric, automobile, idle, wait, automatic, shunting, f0…f28, home, shunting, train, !train | block is true if the loco is in a block "blockID" is true if the loco is in a block with this "blockID" train is true if a train is assigned to the loco !train is true if no train is assigned to the loco |
Car | car | empty, loaded, maintenance, cartype, waybill, f0…f28, "blockID" | See locomotive |
Waybill | waybill | waiting, shipping, delivered, "destinationID", "originID" | |
Text | tx | on, off | In case the toggle switch option is set. |
Class Objects
Object Name | Object type |
---|---|
Block | bk |
Loco | lc |
Route | st |
Commands
Note:
- With "Commands All" all the object commands specified in the Rocrail plan.xml are supported.
- The special implemented action commands are listed separately.
Object Name | Object type | Commands | States | Remark | Example |
---|---|---|---|---|---|
Loco | lc | All https://wiki.rocrail.net/rocrail-snapshot/rocrail/wrapper-en.html#lc | The bkid attribute can be used to get a loco ID from a block. Command "regularreset" is the same as "softreset" but removes the assigned schedule too. | ||
Function | fn | All and fndesc, fncmd, group 1..7 | The fnchanged or the fndesc, function description, attribute signals which function has been changed: f0…f28 (true/false). The fncmd can be used for on/off/flip. | <fn id="loco1" fndesc="Horn" fncmd="flip" group="2"/> F1-F4 group="1" F5-F8 group="2" … F25-F28 group="7" |
|
Switch | sw | All | |||
Signal | sg | All | |||
Accessory Group | accgroup | on, off, flip | |||
Output | co | All | |||
Power | powercmd | on, off | The id is the boosterID. If left empty the command is for all boosters | ||
Block | bk | All, reserve | open, closed | Use lcid in case of reserve command. | <bk id="x" state="closed"/> |
Sensor | fb | All, on, off, flip | |||
Route | st | go, lock, free, classset, classadd, classdel | open, closed | The lock and free command needs the extra attribute locid="myLoco". | <st id="x" state="closed"/> |
Text | tx | showon, showoff, blink, on, off, click | Update event by format attribute. The optional bkid and lcid may be used in the command also. | <tx id="tx1" format="the loco id is %lcid%"/> <text id="xyz" cmd="blink" blink="true"/> |
|
Variable | vr | random, start, stop start, length (for substring) | Set by attribute: value="0" text="zero" To make it temporary set generated="true" Update: with 2.1.3268+ this is the default value To make it static set generated="false" | <vr id="var1" text="Rocrail"/> <vr id="var2" text="@var1-XML-Scripting." tokeniser="-"/> <vr id="var2" text="@var1" start="1" length="3"/> |
|
Action control | actionctrl | The id in the actionctrl is a reference to an existing action. Condition child nodes may be added. | |||
Operator | operator | emptycar, loadcar, addcar, leavecar | In the carids attribute a list of cars must be specified. | ||
System | sys | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#sys | |||
Automat | auto | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#auto | |||
Car | car | empty, loaded, maintenance, assignwaybill, resetwaybill, loco & function | empty, loaded, maintenance, cartype, location | <car id="test" cmd="assignwaybill" waybill="testbill"/> | |
Staging block | sb | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#sb | |||
Fiddle Yard | seltab | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#seltab | |||
Location | location | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#location | <location id="Blaak" cmd="info" svalue="tx1"/> | ||
Clock | clock | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#clock | Set clock on System time: <clock divider="1" hour="%syshour%" minute="%sysmin%"/> |
||
Turntable | tt | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#tt | |||
External | ext | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#ext | |||
Weather | weather | setweather, weathertheme, go, stop | |||
Light | light | flip, enable, disable | Enable a light from LightControl. | ||
LightControl | lightctrl | go, stop | Enable / disable LightControl. | <lightctrl cmd="go"/> <lightctrl cmd="stop"/> |
|
Model | model | All https://rocrail.net/software/rocrail-snapshot/rocrail/wrapper-en.html#model | The modify is not supported, use change instead. | <model cmd="change"> <tx id="x" backred="255" backgreen="0" backblue="0"/> </model> |
|
MVTrack | mv | reset, sets1, sets2, setdistance, setdistanceR | <mv cmd="sets2" s2="fb4712"/> |
Attribute values
If a command attribute value starts with a question mark it will be replaced with attribute value of the referenced object.
Example:
<lc id="loco1" cmd="useschedule" scheduleid="?startupscid"/>
The "?startupscid" value will be replaced with the startupscid of loco1:
20160422.085709.015 r9999I tid0x8BA OXmlScri 0571 execute [lc] id[loco1] cmd[useschedule] oid[] callerid[wefiu] 20160422.085709.016 r9999I tid0x8BA OXmlScri 0521 replaced attribute value: scheduleid="?startupscid" with "1-2" 20160422.085709.017 r9999a tid0x8BA OLoc 3644 <lc id="loco1" cmd="useschedule" scheduleid="1-2"/>
Object IDs
The object IDs may contain variables.
See for possible variables: Text variables
Example
<xmlscript> <tx id="%callerid%-%substate%" format="%lcimg%"/> </xmlscript>
System variables
Variable Format
With the format attribute it is possible to format variable content in the same way as printf.
Example
<xmlscript> <vr id="var1" value="3" text="Hello"/> <vr id="var2" value="5" text="RocrailFans"/> <vr id="var3" format="%s%02d:%04d%s" text="@var1 #var1 #var2 @var2"/> <trace text="@var3"/> </xmlscript>
Output with the format attribute looks like:
Hello03:0005RocrailFans
Output without the format attribute looks like:
Hello 3 5 RocrailFans
Variable Names
Within the limits described above, variable names can be freely named; but as soon as two scripts with the same variable name run at the same time the scripts may not work correctly. In those cases a script specific prefix added to the name of the variable may avoid any confusion:
- change the original variable name from "vr_idx"
- within script "MyScriptNumber1.xml" to the variable name "vr_MSN1_idx" and
- within script "MyScriptNumber2.xml" to the variable name "vr_MSN2_idx" and so on.
Variables defined as "Generated"
In order to store a variable from runtime to runtime in Rocrail, these variables must be defined as "generated" "false":
Example
<xmlscript> <vr id="vr_MSN3_lastUsedLocomotive" value="0" text="br89" generated="false"/> <vr id="vr_MSN3_tmp" value="0" text=""/> </xmlscript>
The variable "vr_MSN3_lastUsedLocomotive" will be stored within the Rocrail plan file.
The variable "vr_MSN3_tmp" will be deleted when Rocrail is finished and will not be stored within the Rocrail plan file.
Tips
XML Well Formed
To check the XMLScript if its well formed it can be opened in a WEB Browser.
Some characters must be escaped:
Char | Escape |
---|---|
< | < |
& | & |
> | > |
Example
This is not well formed but accepted by the Rocrail XML Parser:
condition="#var2%oid% < &time"
To check it with a WEB Browser it must be changed in:
condition="#var2%oid% < &time"
This is also valid for the Rocrail XML Parser.