XML Script logo up prev
Generating data from code
Introduction

Sometimes we need to generate data dynamically, perhaps because a target application demands the data in a different form to that supplied by the originating application. This section describes how we can use code to generate data.


				
Using loops

XML Script supports a range of standard programming constructions, such as _if, _for and _foreach. This example shows how _for can be used to generate output. The _for command requires two attributes, from and to. These determine the value of the index attribute which is used as a counter during processing. As index is an attribute of the _for element, and the _for element is on the template tree, it must be referred to in an interpolation as $.index . With each iteration of the _for loop, the value of index is incremented. In the following script, index is used to drive the calculation of the year of payment of the fixed rate coupon. Note the __maxCR attribute in the XST opening tag - this limits the number of consecutive carriage returns in the output, in this case setting it to 1. Also note that we must use $!index within the PaymentDate element, because we want to retrieve the index attribute of the _for element.

<XST __maxCR="1" __XMLscript='1.1' >

# \.IssueMonth := "April" #
# \.IssueDay := "15" #
# \.IssueYear := "2003" #
# \.Maturity := "10" #

<FixedRateBond Coupon="5.5" Currency="USD" >
	<_for from="1" to="\.Maturity" >
	<PaymentDate ># \.IssueDay # # \.IssueMonth # # \.IssueYear + $!index #</PaymentDate>
	</_for>
</FixedRateBond>

</XST>
Running the script

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

<FixedRateBond Coupon="3.5" Currency="USD" >
        <PaymentDate >15 April 2004</PaymentDate>
        <PaymentDate >15 April 2005</PaymentDate>
        <PaymentDate >15 April 2006</PaymentDate>
        <PaymentDate >15 April 2007</PaymentDate>
        <PaymentDate >15 April 2008</PaymentDate>
        <PaymentDate >15 April 2009</PaymentDate>
        <PaymentDate >15 April 2010</PaymentDate>
        <PaymentDate >15 April 2011</PaymentDate>
        <PaymentDate >15 April 2012</PaymentDate>
        <PaymentDate >15 April 2013</PaymentDate>
</FixedRateBond>
Recursive processing

In the example above, the FixedRateBond element was echoed to output. This in contrast to the _for element, which is not echoed because the processor recognises it as a command. A command element, like _for in the above example, is replaced by its own output (in this case, all of the PaymentDate elements). The processor reviews this output in turn, and - if it knows how - processes that also. If the processor finds an element which is not a command, it checks to see whether any 'method' has been associated with it (associating methods with objects is an advanced topic, not covered here); if not, it uses the default method which is to echo the element to output. In this way, the processor works through a script, evaluating each command and then echoing output which it cannot process further.


				
Using the data tree

There are a number of reasons why you might want to keep elements on the data tree rather than the template tree. One reason is that if we leave data on the template tree it will be processed recursively until, finally, the processor echoes the result to output. Another reason is that it can be quite difficult to address elements on the template tree if the script includes nested templates. Although the _eval command places its output on the template tree by default, you can tell it to place output on the data tree.


				
Generating data with _eval

Using the _eval command with result set to 'data' will redirect script output to the data tree, and thus prevent it being echoed to output. In the following example, we have nested the FixedRateBond element within an _eval element. The _eval command will force the processor to evaluate its content, but when completed the output is placed on the data tree. The FixedRateBond element now resides on the data tree, and will now only be echoed to output if we request it. Note the use of the square brackets in the final interpolation - this can be thought of as an array index or array range. In this case \.Maturity will evaluate to '10', so the range address will identify the tenth PaymentDate element which is a sub-element of FixedRateBond. In XML Script, all array ranges start from 1.

<XST __XMLscript="1.1" >

# \.IssueMonth := "April" #
# \.IssueDay := "15" #
# \.IssueYear := "2003" #
# \.Maturity := "10" #

<_eval result="data" >

<FixedRateBond Coupon="3.5" Currency="USD" >
	<_for from="1" to="\.Maturity" >
	<PaymentDate ># \.IssueDay # # \.IssueMonth # # \.IssueYear + $!index #</PaymentDate>
	</_for>
</FixedRateBond>

</_eval>

The maturity date is # \FixedRateBond\PaymentDate[\.Maturity] #
</XST>
Running the script

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

The maturity date is 15 April 2013
Contents...

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