[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Re: "if-condition-return something" idiom : is it possible in XSLT 1 ?

Subject: Re: [xsl] Re: "if-condition-return something" idiom : is it possible in XSLT 1 ?
From: "Abel Braaksma (Exselt) abel@xxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 16 Jun 2014 16:25:34 -0000

Doing string-manipulations in XSLT 1.0 is painful, the lack of regular expressions, splitting, sequences and type-safety makes it quite to very hard to do. The toolset in 1.0 is limited to substring-after/before, translate and concat. My preferred solution would be to move to XSLT 2.0+ where you can do the C-style if-statements simply in XPath itself: if(condition) then truepart else falsepart. There is a DocBook XSLT 2.0 stylesheet available which may help you: https://github.com/docbook/xslt20-stylesheets, but I'm not sure your situation allows making this move.

The code in your original post will return a concatenation of each if-statement that is true, and the last xsl:value-of will be returned always, which is not what you want, given the C-style example at the top of your post. Others have already commented that you need to use xsl:choose if you have to stick to XSLT 1.0, or let matching templates do the heavy lifting for you.

Because you are trying to parse dates, where the input is of different formats, maybe the highest-rated solution here helps you out in the right direction: http://stackoverflow.com/questions/17079954/convert-date-time-format-in-xslt. It does not cover all your situations, but typically I would approach your problem by:

1. Change the input date-format into a generic date-format
2. Write one named template for parsing the generic date-format into the format you are after

This has the advantage that it is easy to maintain. If you want to change the output format, all you need to do is change the way the generic date-format is formatted. If you ware going to use XSLT 2.0, instead of a generic self-defined format, you can simply use xs:date or xs:dateTime, and use formatDate or formatDateTime for the formatting.

If I had the time I could help you expand the XSLT 1.0 example in the aforementioned link, it would surely benefit the community to have a generic date-time parsing template.

Alternatively, if you don't mind writing extension functions, you can take Clark C. Evans's example for date-parsing, he uses a Java commandlet in a thread of 15 years ago: http://www.stylusstudio.com/xsllist/199910/post70080.html, which might just work with Saxon 6.5 or other Java based processors. It could save you a whole lot of trouble writing it in XSLT 1.0 yourself.


Abel Braaksma
Exselt XSLT 3.0 streaming processor

"Kerry, Richard richard.kerry@xxxxxxxx" <mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
maandag 16 juni 2014 15:11

"you seem to want to replicate C++ programming idioms in XSLT. "

Not at all.

I thought of the process in those terms, as I am far more familiar with C/C++. Having implemented part of the requirement in that way and found the result unsatisfactory I'd like to know how better to do it.

"a verbose and ugly terrain"

That's what I've started seeing and led me to assume that it wasn't the best way to do it - hence the question.

What I am doing is writing a callable template which will give dates in the form yyyy-mm (y and m numeric) when given dates in a variety of formats including those with strings for months (dd MMM yy, dd/mm/yyyy, mm/yy, and many others). So the input is a single string which needs to be tested against a number of different formats and picked apart accordingly. Perhaps I can partly pick it apart then put the parts into a node-set and get a template called on that.

"might look verbose"

I've got at least half a dozen input formats. Before starting to consider this if-condition-return idiom I was getting other ugly/verbose results. If I can get the language processor to do tests for me I'm happy to move to many-templates.



*From:* Ihe Onwuka ihe.onwuka@xxxxxxxxx [xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx]
*Sent:* 16 June 2014 13:44
*To:* xsl-list
*Subject:* Re: [xsl] Re: "if-condition-return something" idiom : is it possible in XSLT 1 ?

XSLT is a pattern matching language, so the short answer is that idiomatic XSLT would use predicates in template rules for this

<xsl:template match="balance[. > 100]">
  things to do if balance is greater than 100

<xsl:template match="balance">
  default processing for balance

which might look verbose but if you code like this the processor will figure out when to fire which rule and what to do next.

This will probably not satisfy you as you seem to want to replicate C++ programming idioms in XSLT. Yes you can do it but there lies a verbose and ugly terrain for which I do not have the energy to travel but maybe someone else does.

XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <-list/2528992> (by email)
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <-list/1238284> (by email <>)
"Kerry, Richard richard.kerry@xxxxxxxx" <mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
maandag 16 juni 2014 14:19
And just to be clear, I am asking about XSLT1.
(I am doing DocBook transformations and am trying to parse dates as strings)


In C/C++ programming the following idiom is quite common:

if (condition1)
return value1;

if (condition2)
return value2;

if (condition3)
return value3;

return value4;

In other words each of these will test a condition and if it is satisfied execution will stop and some value will be returned to the caller. The run stops with the first condition that succeeds.

I've tried to do something similar in XSLT and am getting somewhat contradictory indications of whether or not it is working. Please can someone advise whether this should work, or if there is a similar form that I can use.

What I have is like the following template, to be called by name.

<xsl:template name="test.1">
<xsl:param name="string" select="''"/>

<xsl:if test="$check.1 = 0">
<xsl:value-of select="$value.1" />

<xsl:if test="$check.2 = 0">
<xsl:value-of select="$value.2" />

<xsl:if test="$check.3 = 0">
<xsl:value-of select="$value.3" />

<xsl:value-of select="$value.4" />

My theory of why it might work is based on knowing that the following will work:

<xsl:template name="test.2">
<xsl:param name="string" select="''"/>

<xsl:value-of select="$value.4" />

I say "will work" in the sense that if the above template is called (by name) it will return the value from value.4. What I'm not sure of is whether that should work if the "returning" value-of is a level down, in an xsl:if, as in the other template (test.1).
It is only a theory of why it might work. Practice may indicate otherwise, and somewhere in the spec might be a reason.

Can someone please advise whether I can do this, or how to get broadly equivalent behaviour ?


Richard Kerry
BNCS Engineer, SI SOL Telco & Media Vertical Practice
T: +44 (0)20 3618 2669
M: +44 (0)7812 325518
G300, Stadium House, Wood Lane, London, W12 7TA

This e-mail and the documents attached are confidential and intended solely for the addressee; it may also be privileged. If you receive this e-mail in error, please notify the sender immediately and destroy it. As its integrity cannot be secured on the Internet, the Atos group liability cannot be triggered for the message content. Although the sender endeavours to maintain a computer virus-free network, the sender does not warrant that this transmission is virus-free and will not be liable for any damages resulting from any virus transmitted.

Current Thread