X2Shell Console Application Language

X2Shell

Originally code named “Batch Runner and Diagnostics for Operating/Networking” (BRANDON), X2Shell was developed as a toolkit to allow sysops and technicians to develop their own apps for performing various tasks. X2Shell apps can access SQL databases, make HTTP calls, send emails, and of course, work with files.

To make your own X2Shell application, simply copy X2Shell.exe to MyAppName.exe and make a new config file called MyAppName.xml. Then, edit the config file and start building as shown below. When you run an X2Shell app, the underlying code creates a memory-only working XML file, called the DataCloud, initially comprised of data collected from the environment. It then walks through the configuration file provided. Any Data elements are copied into the DataCloud(tests permitting) and any Run elements are further stepped through and their executions are performed. Every execution adds its results to the DataCloud and is also able to leverage from the any prior data or execution, as well as the original snapshot of the environment.

By default, the XML-based configuration file, is the given the same name of the EXE that was provided, and can consist of any valid root node, which then contains one or more <Data> or <Run> elements. Both of those elements may contain a ‘test’ attribute. The test should be in the style of an XPath, where a node hit is a pass and a miss is a fail. If no test exists, it is an automatic pass. Each Data element that passes will be copied as is into the Data Cloud. Each Run element can contain any combination of the below Execution Types.


Example (HelloWorld.xml)

<HelloWorld>
<echo>
<line>
Hello World!
</line>
<string>
At the tone, the time will be:
</string>
<string type="XPath">
/X2Shell/run-time/@systemtime
</string>
<line>
BEEP!
</line>
</echo>
</HelloWorld>

Result

C:\> HelloWorld.exe
Hello World!
At the tone, the time will be: 4/18/2020 10:25:42 PM
BEEP!

NOTE: Unless otherwise configured, the resultant data cloud will have a root element named “X2Shell”. To change this, include an attribute named “root-node” with a desired value in the root node of your configuration XML, or include the attribute “use-root” with either “yes” or “true” to use the name of your configuration XML root node as the data cloud root name.

Execution Types

The following are the types of exeuctions that can be performed. They will be the name of the XML element being performed within a Run or batch block.

Basic Commands

If you start by thinking of an X2Shell application as a powerful BAT file, then these commands or their concepts should be somewhat familiar to you. They are just executed a little differently than their BAT file counterparts.

echo

Write some text out to the console, or file (see output)

{ any text to be output }
-OR-
any combination of
<string>
...
</string>
and
<line>
...
</line>
Base Attributes:
new-line=="true|false"

Note: unlike most other commands, the echo execution does not have a <params> node, but instead allows complex strings to be created in the same fashion as complex arguments are creaed in the command process. The desired output is generated from any combination of <string/> or <line/> nodes.


Example

<echo id="ShowUsage" test="(count(/X2Shell/run-time/command-line/arguments/arg) = 1)">
<string>
[
</string>
<string type="xpath" no-preceding-whitespace="true">
/X2Shell/run-time/command-line/arguments/arg
</string>
<string no-preceding-whitespace="true">
] - v1.0
</string>
<line>
This program does some cool stuff
</line>
</echo>

Result

C:\> MyProgram.exe
[MyProgram.exe] - v1.0
This program does some cool stuff

pause

============================================================================== “pause” – Hold processing for some intervention —————————————————————————— Params: method=”console|msgbox|timer” timeout=”number-in-milliseconds” (for timer only) caption=”” text=”” buttons=”ok|ok-cancel|yes-no|yes-no-cancel|retry-cancel| abort-retry-cancel”

path

============================================================================== “path” – Used to get or set the working dir, or list the contents of a path —————————————————————————— Params: command=”get-cwd|set-cwd|list|exists|file-exists|… … copy|move[-file]|move-dir[ectory]|delete|make-directory|make-dir|mkdir” filepath=”somefilepath” (optional – “cwd” is default) destpath=”somefilepath” (only used for “copy” or “move”) This is used to manipulate a local drive or network drive path, or context.

output

============================================================================== “output” – Specify where echo content should be sent —————————————————————————— Params: method=”console|file|both|close” filepath=”somefilepath” filemethod=”create|append” The output command with the file (or both) method, forces all echo statements from that point forward to be sent to the filepath specified. If the filemethod is set to append, then the output file will be opened for and the echo statements will be written at the end, otherwise, any existing content before the output command was issued will be overwritten. The overriding of the echo command will continue until either a new output command is given, or the program terminates.

Spawn Processes

command

============================================================================== “command” – Launch a new process / executable or shell extension —————————————————————————— Params: command=”some.exe” working-directory=”c:\” arguments=”/arg1 /arg2″ (*NOTE: see below) use-shell=”true|false” style=”min|max|hidden|normal” wait-for-exit=”true|false” capture-stdin=”true|false” (**NOTE: see below) capture-stdout=”true|false” capture-stderr=”true|false” * NOTE: Additional arguments may be given as <arg> nodes within the Param. These arg nodes should have the inner text reflecting the value to be used. Further, arg nodes may have “type” and “format” attributes, which will act exactly as the “_type” and “_format” suffixed attributes explained below. For more flexibility, the <arg> nodes also support two additional attributes: “no-preceding-whitespace” and “separator-character”. Giving the first of these a “true” value will simply instruct the argument builder to not add a space between it and the previous arg node. You may instead give your own separator value to be used instead of a space (” “). (i.e. separator-character=”+” ) **NOTE: The option to capture standard input is only used if use-shell = true. Further, an additional node given as <stdin> must be provided within the Param parent node. Like the <arg> nodes above, it supports type and format.

powershell

============================================================================== “powershell” – Run a PowerShell script or applet —————————————————————————— Params: working-directory=”c:\” capture-stdout=”true|false” NOTE: See definition for the “command” action for argument usage

Execution Control

reset

============================================================================== “reset” – Resets the DataCloud to remove all prior execution information —————————————————————————— Params: method=”soft|hard” Both resets will clear the DataCloud, but use a different manner. The soft reset will remove all prior exeuction nodes. The hard reset will rebuild the DataCloud from scratch. A hard reset will also update the systemtime.

run-batch

============================================================================== “run-batch” – Process another batch of commands (typically from transform) —————————————————————————— Params: { List of commands to be run }

dump-log

============================================================================== “dump-log” – Used to dump the current datacloud out to a file or console —————————————————————————— Params: filepath=”output.xml” (or empty for console) rootnode-xpath=”xpath-to-element” (default = “/”) Write out all or part of the XML of the datacloud

stop-if

============================================================================== “stop-if” – Stop processing if this command is run —————————————————————————— Params: method=”this-run|all”

skip-to

============================================================================== “skip-to” – Skip processing if this command is run —————————————————————————— Params: nextCommandType=”{ any valid command type }” (i.e. “pause”) nextCommandId=”{ id of an upcoming command }” end=”true” (actual value is ignored, must be non-empty text)

Transformations

transform

============================================================================== “transform” – Used to apply an external XSL file to a portion of the datacloud —————————————————————————— Params: filepath=”somefile.xsl” source-filepath=”somedocument.xml” -OR- rootnode-xpath=”/datacloud/xpath” The XSL will be applied to the datacloud, optionally at the rootnode-xpath. -OR- By specifying a source-filepath, an external document will be used. NOTICE: An XSLT may be embedded inline as well by NOT specifying a filepath, and instead including an <inline> element with a full XSLT contained Example: <transform> <params rootnode-xpath=”/datacloud/xpath”> <inline> <xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org…”> … </xsl:stylesheet> </inline> </transform>

x2tl

============================================================================== “x2tl” – Apply an {{ X2 Templating Language }} Template against the datacloud —————————————————————————— Params: execute-results=”true|FALSE” Template: (The first element in the commend that is NOT the params) Example: {{ Template }} ==============================================================================

In-Memory Byte Array

clear-bytes

============================================================================== “clear-bytes” – Used to empty out the binary data byte array (bytes) —————————————————————————— Clears out the “bytes” byte array when the contents are no longer needed.

compress-bytes

============================================================================== “compress-bytes” – Used to compress the binary data byte array (bytes) —————————————————————————— Performs ZIP compression on the “bytes” byte array, compressing the contents

decompress-bytes

============================================================================== “decompress-bytes” – Used to empty out the binary data byte array (bytes) —————————————————————————— Performs ZIP decompression on the “bytes” byte array, exploding the contents

User Interface

form

============================================================================== “form” – Build a GUI Dialog Box —————————————————————————— gui: definition gui Attributes: background-color=”” control-box=”true|false” minimize-box=”true|false” maximize-box=”true|false” auto-scroll=”true|false” show-icon=”true|false” show-in-taskbar=”true|false” icon=”” background-image=”” width=”300″ height=”200″ Note: unlike others, the “form” execution does not have a <params> node, but instead allows for a complete UI form to be defined in the XML as a child element called “gui”. A “gui” element can have one or more “layout” elements with attributes: layout Attributes: left=”0″ top=”0″ A “layout” can then have any of the following elements with attributes: label: label Attributes: use-mnemonic=”false” border-style=”none” textbox: textbox Attributes: border-style=”none” scroll-bars=”both” multi-line=”true” password=”false” password-char=”” read-only=”false” button: button Attributes: use-mnemonic=”false” style=”flat” use-style-backcolor=”true” type=”none|yes|no|abort|retry|cancel|ignore” form-accept=”false” form-cancel=”false” image: image Attributes: path=”” border-style=”none” checkbox: checkbox Attributes: auto-check=”true|false” appearance”normal” auto-ellipsis=”true|false” checked=”false|true” check-state=”checked|unchecked” radio: radio Attributes: auto-check=”true|false” appearance”normal” auto-ellipsis=”true|false” checked=”false|true” combobox: combobox Attributes: drop-down-width=”” A “combobox” should contain one or more “item” elements item Attributes: caption=”” listbox: listbox Attributes: allow-multiple=”false|true” A “listbox” should contain one or more “item” elements (see above) checked-listbox: A “checked-listbox” should contain one or more “item” elements (see above) numeric: numeric Attributes: (N/A) date: date Attributes: min-date=”” max-date=”” show-up-down=”false|true”

External Data

http

============================================================================== “http” – Used to get or post contents via HTTP web request —————————————————————————— Params: method=”get|post” uri=”http://….” post-rootnode-xpath=”/” (if method is “post”, what is sent) post-format=”text|xml” (and what format is it sent in)

mail-to

============================================================================== “mail-to” – Used to send results to one or more e-mail recipients. —————————————————————————— Params: smtp-host=”” (either IP address or DNS name of SMTP server) tcpip-port=”25″ (optional – can change for custom port) from=”” (email address of sender) to=”” (one or more email addresses of recipients) subject=”” credentials=”network|none” (if server requires authorization) uri=”http://….” rootnode-xpath=”/” (path to what is being sent) format=”text|xml” (and what format is it sent in)

msmq

============================================================================== “msmq” – Used to send, receive or list contents of a Microsoft Message Queue. —————————————————————————— Params: queue-name=”.\Private$\MyQueue” (path/name of MSMQ) method=”send|receive|list” (note: “list” is non-destructive) rootnode-xpath=”/” (if “send”, path to what is being sent) format=”text|xml” (and what format is it sent in) priority=”lowest|very-low|low|normal|above-normal| high|very-high|highest” (default is “normal”)

sql

============================================================================== “sql” – Perform a Microsoft SQL Server Execution —————————————————————————— Params: method=”recordset|xml|bytes|execute-only” server=”sqlserver\instance” connect=”DataSource=Connection_String” query=”exec my_query @param1, @param2″ row-label=”mydataitem” (default: row) For standard recordsets, the row-label (default is “row”) will be used for each entry in the resulting recordset, with the field names as attributes. NOTE: When using recordset (default) method, do NOT use spaces or special characters for the names of the columns, or you will generate an error. NOTE: Use of the bytes return type will store the resulting single image response in the general byte array “bytes”. If the result will be XML (for instance using the FOR XML option of SQL) use the xml method, and the row-label to indicate the wrapper element. NOTE: If your query or stored procedure has parameters, include them as “param” child elements of the “params” element. Give them a “name” attribute, a “value” attribute, and optionally a “test” attribute. No value attribute will indicate a NULL. A value format of “bytes” to use the general byte array. Example: <sql id=”…” test=”” xpath=””> <params server=”” connect=”” query=”exec my_sproc @p1, @p2, @pImage”> <param name=”@p1″ value=”1″/> <param name=”@p2″ /> <param name=”@pImage” value_type=”bytes”/> </params> </sql>

registry

============================================================================== “registry” – Manage the machine registry (get, set, create, list) ** NOTICE: USE WITH CAUTION!! ** —————————————————————————— Params: hkey=”HKLM|HKCU|HKCR|HKU|HKCC|HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER| HKEY_CLASSES_ROOT|HKEY_USERS|HKEY_CURRENT_CONFIG” subkey=”” method=”get(-value)|set(-value)|create(-key)|list” value-name=”” value-type=”REG_SZ|REG_DWORD” value-data=”” format=”text|xml” Either get, set, create or list a subkey within a branch of the registry.

Compress / Decompress

compress

============================================================================== “compress” – Used to ZIP a file —————————————————————————— Params: filepath=”compressed.zip” mode=”create|update” source-filepath=”some-file-to-compress” saveas-filepath=”directory/path/file_name.ext” delete-onsuccess=”false|true” Either create a new or update an existing ZIP file by adding the source file and saving it in the ZIP as the specified filepath. If delete-onsuccess, then the source file will be deleted after compression.

zip

============================================================================== “zip” – (aka zip-files) Creates or Updates a ZIP file from one or more files —————————————————————————— Params: filepath=”some-files-to-zip*.*” destpath=”my-zip-file.zip” action=”ADD | move” overwrite=”true | FALSE” If the action is set to “move”, the source file will be deleted once added If overwrite is set to “true” then any pre-existing zip will be overwritten Example: <zip id=”…” test=”” xpath=””> <params filepath=”” destpath=”” action=”” overwrite=”” /> </zip>

unzip

============================================================================== “unzip” – (aka unzip-files) Expands a ZIP file to a specified directory —————————————————————————— Params: filepath=”source-file-name.zip” destpath=”file-path-to-extract-into” Example: <unzip id=”…” test=”” xpath=””> <params filepath=”” destpath=”” /> </unzip>

list-zip

============================================================================== “list-zip” – (aka read-zip) Lists the contents of a ZIP file —————————————————————————— Params: filepath=”source-file-name.zip” Example: <list-zip id=”…” test=”” xpath=””> <params filepath=”” /> </list-zip>

Miscellaneous

new-id (guid)

============================================================================== “new-id” – (aka guid) Used to generate one or more GUIDs —————————————————————————— Params: count=”1″


X2Shell

Code named ”BRANDON” (Batch Runner and Network Diagnositics tool), this is a .Net application engine that allows for building complex command-line executables using simple XML configuration files and leveraging the multiple extensions available, including HTTP, SQL, and simple File based operations, as well as leveraging X2TL and the overall X2A2 architecture.

Check out the documentation

L337 (“Leet”) Forms

As our needs for complex workflows, custom user interface gadgets, and more were added to our system, the Quizlets technology was getting pushed to its limits. Rather than continue pushing, we created a new version of the concept, where interface, business rules, and data all existed within a living document, known as L337 (pronounced “Leet” – short for “Elite”) Forms.

This new technology once again eased the development, review and deployment process of new or even simply newly-revisioned forms. L337 Forms were used by the Michigan Health Information Network (MiHIN) with their Health Reimbursements Arrangements (HRA) project, which took a CCD Document as its original data source, and then created a user interface leveraging data points within the base CCD as well as environmental and application data, and creating a living form that was able to generate a corresponding HRA formatted output at any time.

Clinical Architecture

We began working with Clinical Architecture on the Social Security Administration E-Disability project. Soon after, we established a closer working relationship, leveraging our Alchemy product’s ability to ingest and output multiple different data formats (HL7, CCD, etc.) and their ability to map between multiple data dictionaries (ICD-9, CPT-4, etc.). We quickly realized that a combined solution would solve many interoperability hurdles faced by healthcare today, causing launch of PIVOT. We have since assisted in furthering their PIQI Framework by creating a PIQI document from any PIVOT (aka Alchemy) source.

X2A2

built to replace the outdated Visual Basic (VB6) WebClass Architecture

Tested and Certified by Microsoft as a .Net Application Engine

Ran EXR/CPNG for dozens of interface engines as well as the main web-based application engine.

Read more about it here.

SQL Data Model

The SQL Data Model is a third-normal-form based model, with nearly all tables using large integer Identity based keys, providing performance and referential integrity.  The Data Model began with our Clinical Data Repository (CDR-Web), focusing on the primary portions of a patient record: Demographics, Procedures, Diagnoses, Lab Results and so on.  In CDR-Web’s product evolution, this expanded to include Order Entry, Medications, Pharmacy Order Entry, and Scanned Documents. 

During our partnership with HFHS for EXR/CPNG, our data model was chosen for the basis of the new product, and was enhanced to support Teams, Work Queues, Clinical Documentation, Pathways/Protocols, and much more.  At one point, out of curiosity, one of the HFHS data model team printed the entire logical model. It took up his entire wall.

We continued to expand EXR to be certified as a complete Inpatient and Outpatient EHR, and the Data Model was further enhanced to support some of the feature points, and encryption methods required for certification.

When we created Arcana, we enhanced the Data Model for all of our external sourced data tables and expanded them to fully accept any sourced data. This allows us to accept data from any combination of source systems, and be properly aggregated, preserving the original while at the same time being able to easily map it to any known Point-of-Truth (i.e. CPT, ICD and similar codesets).  With it, Arcana is able to assess patients realtime and have reaction situations for any number of use cases, including aiding in insurance reporting of HEDIS matching patients and their related data points.