User Tools

Site Tools


xmlscripting-en

XMLScript

Warning

  1. Do not replace standard Rocrail functions with XMLScript.
  2. Do not try to mangle the automatic Rocrail engine.
  3. The scripts are executed asynchrone, and needs multithreading programming know how.
  4. If encountering unexpected behaviour: Turn off XMLScript actions.
  5. If uncertain: Do not use XMLScript, or ask for help in the Forum.
  6. Do not use the same variables in multiple XMLScripts, which will be set to new values, to avoid unexpected results including Server crashes.

D I S C L A I M E R


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!

  1. Create a XMLScript and save it in a file. (See: Simple Example)
  2. Create a "run ext. program" action.
  3. Select the XMLScript file. (If the script file is in the workspace directory a path is not necessary.)
  4. 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:

Open the editor. Parser error detected after validate or save.

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
< &lt;
& &amp;
> &gt;

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% &lt; &amp;time"

This is also valid for the Rocrail XML Parser.


1)
An XML document with correct syntax is called "Well Formed".
2)
10073+
3)
12.545+
xmlscripting-en.txt · Last modified: 2024/02/15 10:43 by rjversluis