Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xslt coalesce function with Saxon

Tags:

xslt

Does anyone know of a built in function for performing a coalesce in XSLT, or will I need to write my own?

I have some xml like this:

<root>
 <Element1>
   <Territory>Worldwide</Territory>
   <Name>WorldwideName</Name>
   <Age>78</Age>
 </Element1>
 <Element1>
   <Territory>GB</Territory>
   <Name>GBName</Name>
 </Element1>
</root>

The second element1 (GB Territory) is completly optional and may or maynot occur, however when it does occur it takes precedence over the the WorldWide Territory.

So what I was after is something like the the coalesce below:

<xsl:variable name="Worldwide" select="root/Element1[./TerritoryCode ='Worldwide']"/>
<xsl:variable name="GB" select="root/Element1[./TerritoryCode ='GB']"/>

<xsl:variable name="Name" select="ext:coalesce($GB/Name, $Worldwide/Name)"/>

The id being that variable Name in the above example will contain GBName.

I know I could use the xsl:choose, but I have some places where there are 4 places it could look and the xsl:choose just becomes messy and complicated, so was hoping to find a built in function, but had no luck so far.

Thank you.

like image 784
Steve Goodman Avatar asked Sep 05 '13 21:09

Steve Goodman


People also ask

Can we reassign a value to variable in XSLT?

Variables in XSLT are not really variables, as their values cannot be changed. They resemble constants from conventional programming languages. The only way in which a variable can be changed is by declaring it inside a for-each loop, in which case its value will be updated for every iteration.

How do I write a function in XSLT?

Add the <msxsl:script> element to the template's markup within which you will add your C# functions. Add the function within the <msxsl:script> element. Keep all your functions within a CDATA element. Now you can directly call the C# function in your XSLT prefixing its name with “csharp” namespace.

What is Number () in XSLT?

Specifies the format pattern. Here are some of the characters used in the formatting pattern: 0 (Digit) # (Digit, zero shows as absent)


1 Answers

In XSLT 2.0 you could just create a sequence of items from your variables and then select the first one with a predicate filter:

<xsl:variable name="Name" select="($GB/Name, $Worldwide/Name)[1]"/>

The predicate filter will select the first non-null item in the sequence.

For instance, this would still produce "GBName":

<xsl:variable name="emptyVar" select="foo"/>
<xsl:variable name="Worldwide" select="root/Element1[Territory ='Worldwide']"/>
<xsl:variable name="GB" select="root/Element1[Territory ='GB']"/>

<xsl:variable name="Name" select="($emptyVar, $GB/Name, $Worldwide/Name)[1]"/>
like image 149
Mads Hansen Avatar answered Sep 25 '22 15:09

Mads Hansen