XML Script logo next up prev
The XML trees
The template tree

The processor treats the XML Script template as a tree of XML, which we refer to generally as the code, or template tree. This tree is made up of the elements, attributes and content which comprise an XST.

The data tree

For convenience, the processor also uses a second tree, the data tree, which typically contains XML data. Using a distinct data tree allows us to make references to data variables which can remain constant even though accessed from different scripts or templates. In general, the data tree is used to store data for processing, while the template tree can be used to store temporary variables which are used within a particular template.

Distinguishing between trees

Both template and data trees use the backslash to identify elements and the dot to identify attributes. By default, an interpolation will refer to the data tree. Thus the interpolation \invoice refers to the root-level invoice element on the data tree. To refer to the template tree a dollar sign is pre-pended to the interpolation string, such as $\invoice .

Nested templates

In more complex applications, it is often necessary to nest scripts so that one template, or script, may be a sub-element of another. When templates are nested or applied to data elements, the "current location" in the data and template trees changes. The start location for an interpolation will move to be relative to the current template and current data item.

Using the data tree

When processing a data element using a template, data tree interpolations are always performed relative to that data element. On the data tree, \ will always return the root of the data tree. Whilst an XML Script is executing, there is only one data root. Thus it's a good place to store data that needs to be accessed by the whole script, such as configuration parameters. We'll use the _foreach command to loop over a collection of item elements and pretty-print them. Note how the "current location" in the data tree changes to reflect which item we are actually processing, and that the data root does not change.

<XST __XMLscript="1.1" >
<_data >
<invoice id="1234" >
	<item name="jacket" price="95.99" />
	<item name="skirt" price="35.00" />
	<item name="coat" price="42.25" />
</invoice>
</_data>

<_foreach element="\invoice\item" >
	Invoice id: # \invoice.id #
	# .name # at # .price #
</_foreach>

</XST>
Running the script

Save the above script to a file in the directory where X-Tract is installed, and name it ForeachExample.xst. Run it using the command xtract ForeachExample.xst. It will generate the following output:

	Invoice id: 1234
	jacket at 95.99

	Invoice id: 1234
	skirt at 35.00

	Invoice id: 1234
	coat at 42.25
Using the template tree

Template tree interpolations are performed relative to the template actually running. The interpolation $\ returns the root of the current template. It's necessary to use this because each sub-element on the template side changes where the "current location" is. We need to have access to the top of the currently running template, which is useful for storing temporary variables (we can also use inherited access to create local variables in templates, described below). In the example script, note how we must store the sub-total at the root of the current template, since within the Subtotal element an interpolation on the template side will have its "current location" in the template tree set to Subtotal, not _foreach.

<XST __XMLscript="1.1" >
<_data >
<invoice id="1234" >
	<item name="jacket" price="95.99" />
	<item name="skirt" price="35.00" />
	<item name="coat" price="42.25" />
</invoice>
</_data>

<_foreach element="\invoice\item" >
	# $\.total := $\.total + .price #
	<Subtotal > # $\.total # </Subtotal>
</_foreach>

</XST>
Running the script

Save the above script to a file in the directory where X-Tract is installed, and name it ForeachExample2.xst. Run it using the command xtract ForeachExample2.xst. It will generate the following output:

	<Subtotal > 95.99 </Subtotal>

	<Subtotal > 130.99 </Subtotal>

	<Subtotal > 173.24 </Subtotal>
Meta-attributes

The processor assigns 'meta-attributes' to each element in the tree, which can be interrogated using interpolations. The most useful meta-attributes are __tag (which returns the name of the tag used to describe an element), __content (which returns text content and sub-elements), __text_content (which returns only the text content and not the sub-elements), and __element (which returns the element's tags, attributes and all content).

Interrogating the tree

Now change the AssignmentByExample.xst file, as shown below. The three interpolations will give us a clear picture of the data tree. The first one will return the invoice element and all its content. The second one will return the tag name of the invoice element - obviously, this will be 'invoice'. The last one uses the additional syntax \.. to tell the processor to look for the parent element, rather than the child element, of invoice. The parent element in this case is __data_root. Note that you should not try to refer to the __data_root element directly, as X-Tract considers it as a special sort of element called a 'virtual' element.

<XST __XMLscript="1.1" >
<_data >
<invoice >
	<item name="jacket" price="95.99" />
	<item name="skirt" price="35.00" />
	<item name="coat" price="42.25" />
</invoice>
</_data>

# \invoice.__element #

Child name is # \invoice.__tag #
Parent name is # \invoice\...__tag #

</XST>
Running the script

Save the above script back to the same file and run it using the command xtract AssignmentByExample.xst. It will generate the following output:

<invoice >
        <item name="jacket" price="95.99" />
        <item name="skirt" price="35.00" />
        <item name="coat" price="42.25" />
</invoice>

Child name is invoice
Parent name is __data_root
Attribute inheritance

By default, XML Script assumes that you do not want attributes to be inherited. The interpolation \# item.id \# will only return content if the item element actually has an id attribute. If we wish to access an inherited attribute, we can use the bang character in an interpolation. For example, \# item!id \# will return the id attribute of item if it has one, and if not it will query the parents of item until finding an id attribute or running out of parent elements. Setting non-inherited attributes works in the obvious way, but setting inherited attributes will search for the required attribute and set it wherever it is found. If a matching attribute is not found, one will be created on the original child object.

<XST __XMLscript="1.1" >
<_data >
<invoice id="1234" >
        <item name="jacket" price="95.99" />
        <item name="skirt" price="35.00" />
        <item name="coat" price="42.25" />
</invoice>
</_data>

jacket's id attribute: # \invoice\item[1].id #
jacket's inherited id attribute: # \invoice\item[1]!id #

Setting jacket's inherited id attribute...
# \invoice\item[1]!id := "9876" #
invoice's id attribute: # \invoice.id #
jacket's id attribute: # \invoice\item[1].id #

Setting jacket's id attribute...
# \invoice\item[1].id := "jck001" #
jacket's id attribute: # \invoice\item[1].id #
</XST>
Running the script

Save the above script to a file in the directory where X-Tract is installed, and name it InheritanceExample.xst. Run it using the command xtract InheritanceExample.xst. It will generate the following output:

jacket's id attribute: 
jacket's inherited id attribute: 1234

Setting jacket's id attribute...

invoice's id attribute: 9876
jacket's id attribute: 

Setting jacket's id attribute...

jacket's id attribute: jck001
Inheritance in practice

In the following example, the interpolation $!__XMLscript refers to the __XMLscript attribute of the _set element, because this is the "current location" in the template tree. Because we have requested an inherited attribute, the interpolation returns '1.1', which is the value assigned to the __XMLscript attribute in the grandparent element. In this case, the interpolation could also have been written as $\.__XMLscript , referring to the __XMLscript attribute of the current template. Note that you should not include elements or attributes starting with 'XML' (in upper or lower case) in scripts, as such names are reserved for special uses in XML.

<XST __XMLscript="1.1" >

<_set name="\invoice\info" >
This invoice information was 
generated by X-Tract using the 
XML Script language version # $!__XMLscript #.
</_set>

# \invoice #

</XST>
A fully-functional script

The concepts covered so far allow you to create fully-operational programs. In this example a data tree element, invoice, is created and a sub-element, info, is inserted into it using the _set command. A series of assignments establish data tree variables and then assign them, in turn, to a new element within the existing data tree. Note the use of the sum() and round() functions within the interpolations. Finally, the completed invoice element is echoed to output, using the interpolation \invoice.__element .

<XST __XMLscript="1.1" >

<!--
	Establish invoice element at the data root
-->
	
<_data >
<invoice >
	<item name="jacket" price="95.99" />
	<item name="skirt" price="35.00" />
	<item name="coat" price="42.25" />
</invoice>
</_data>

<!--
	Insert info element into invoice element
-->

<_set name="\invoice\info" >
This invoice information was 
generated by X-Tract using the 
XML Script language version # $!__XMLscript #.
</_set>

<!--
	Calculate invoice totals
-->

# \.tax_rate := '.175' #
# \.gross := sum( \invoice\item.price )#
# \.net := round( \.gross / ( 1 + \.tax_rate ),2 ) #
# \.tax := \.gross - \.net #

<!--
	Assign values to invoice element
-->

# \invoice\total.gross := \.gross #
# \invoice\total.net := \.net #
# \invoice\total.tax := \.tax #

<!--
	Echo invoice element to output
-->

# \invoice.__element #

</XST>
Running the script

Save the above script to a file in the directory where X-Tract is installed, and name it Invoice.xst. Run it using the command xtract Invoice.xst. It will generate the following output:

<invoice >
        <item name="jacket" price="95.99" />
        <item name="skirt" price="35.00" />
        <item name="coat" price="42.25" />
<info >
This invoice information was
generated by X-Tract using the
XML Script language version 1.1.
</info>
<total gross="173.24" net="147.44" tax="25.8" />
</invoice>
Next...

XML Script homepage | Documentation home | XML Script docs | Command list | Function list | X-Tract docs

X-Stream, X-Tract and XML Script are trade marks of DecisionSoft Limited
© Copyright 1998-2000 DecisionSoft Limited