XMILE is an open standard for describing system dynamics models in XML. Version 10 of iThink and STELLA output their models in the XMILE format. One of the advantages of XML is that it is a text-based format that can be easily queried and manipulated. This post will show you how to use XMLStarlet, a free XML command line management tool available for Windows, Macintosh, and Linux, to easily extract information from a XMILE model. It will also demonstrate how to modify the XML style sheet (XSLT) generated by XMLStarlet to create custom HTML reports.
Our goal is to create a report that lists the stocks, flows, and converters in the susceptible-infected-recovered (SIR) model of infection shown below (available by clicking here). Each model variable will be listed with its own equation and sorted by name.
XMLStarlet uses the select command (sel) for making queries to an XML file and formatting the results. We will use all of the following select command options:
-t (template): define a set of rules (below) to be applied to the XML file
-m “XPath query” (match): find and select a set of nodes in the XML file
-s <options> “XPath expression” (sort): sort selected nodes by XPath expression
-v “XPath expression” (value): output value of XPath expression
-o “text” (output): output the quoted text
-n (newline): start a new line in the output
Reporting Stock Names
Let’s start by outputting the names of the stocks in the model. In a XMILE file, stocks are identified by the <stock> tag, which is nested inside the <xmile> and <model> tags:
<xmile …> <model> <stock name="Infected"> <eqn>1</eqn> </stock> </model> </xmile>
There is one <stock> tag for every stock in the model and each stock has, at a minimum, both a name (in the “name” attribute) and an initialization equation (in the <eqn> tag). To get the names of all stocks in the model, we can build a template using these XMLStarlet command options:
sel –t -m “_:xmile/_:model/_:stock” -v “@name” -n
The “sel” chooses the select command and the –t begins the template (the set of rules used to extract and format information from the XML file). The –n at the end puts each stock name on its own line.
The –m option defines the XML path to any stock from the root. In this case, the –m option is selecting all the XML nodes named stock (i.e., <stock> tags) that are under any <model> tags in the <xmile> tag. From the XMILE file, one might expect the XML path to be “xmile/model/stock,” but the tags in the XMILE file are in the XMILE namespace and XPath, which is being used for this query, requires namespaces to be explicitly specified. Luckily, XMLStarlet, starting in version 1.5.0, allows us to use “_” for the name of the namespace used by the XML file, in this case the XMILE namespace. Thus, every XMILE name in a query must be preceded by “_:”.
Finally, the –v option allows us to output the name of each node selected with -m (stocks, in this case). The “@” tells XPath that “name” is an attribute, not a tag, i.e., it is of the form name=”…” rather than <name>…</name>.
To build a full command, we need to add the path to XML Starlet to the beginning and the name of the XML file being queried to the end:
XMLStarlet_path/xml <options above> SIR.stmx
The entire command without the path to XMLStarlet is:
xml sel -t -m “_:xmile/_:model/_:stock” -v “@name” -n SIR.stmx
This command produces the following output: