Wildcards!
- by Tim Dexter
Yes, its been a while, Im sorry, mumble, mumble ... no excuses. Well other than its been, as my son would say 'hecka busy.' On a brighter note I see Kan has been posting some cool stuff in my absence, long may he continue!
I received a question today asking about using a wildcard in a template, something like:
<?if:INVOICE = 'MLP*'?> where * is the wildcard
Well that particular try does not work but you can do it without building your own wildcard function. XSL, the underpinning language of the RTF templates, has some useful string functions - you can find them listed here. I used the starts-with function to achieve a simple wildcard scenario but the contains can be used in conjunction with some of the others to build something more sophisticated.
Assume I have a a list of friends and the amounts of money they owe me ... Im very generous and my interest rates a pretty competitive :0)
<ROWSET>
<ROW>
<NAME>Andy</NAME>
<AMT>100</AMT>
</ROW>
<ROW>
<NAME>Andrew</NAME>
<AMT>60</AMT>
</ROW>
<ROW>
<NAME>Aaron</NAME>
<AMT>50</AMT>
</ROW>
<ROW>
<NAME>Alice</NAME>
<AMT>40</AMT>
</ROW>
<ROW>
<NAME>Bob</NAME>
<AMT>10</AMT>
</ROW>
<ROW>
<NAME>Bill</NAME>
<AMT>100</AMT>
</ROW>
Now, listing my friends is easy enough
<for-each:ROW> <NAME> <AMT> <end for-each>
but lets say I just want to see all my friends beginning with 'A'. To do that I can use an XPATH expression to filter the data and tack it on to the for-each expression. This is more efficient that using an 'if' statement just inside the for-each.
<?for-each:ROW[starts-with(NAME,'A')]?>
will find me all the A's. The square braces denote the start of the XPATH expression. starts-with is the function Im calling and Im passing the value I want to check i.e. NAME and the string Im looking for. Just substitute in the characters you are looking for.
You can of course use the function in a if statement too.
<?if:starts-with(NAME,'A')?><?attribute@incontext:color;'red'?><?end if?>
Notice I removed the square braces, this will highlight text red if the name begins with an 'A'
You can even use the function to do conditional calculations:
<?sum (AMT[starts-with(../NAME,'A')])?>
Sum only the amounts where the name begins with an 'A' Notice the square braces are back, its a function we want to apply to the AMT field. Also notice that we need to use ../NAME. The AMT and NAME elements are at the same level in the tree, so when we are at the AMT level we need the ../ to go up a level to then come back down to test the NAME value.
I have built out the above functions in a sample template here.
Huge prizes for the first person to come up with a 'true' wildcard solution i.e. if NAME like '*im*exter* demand cash now!