Simple XSLT ifnull for numbers

Answer to question how to display zero instead of NaN in XSLT for non existing node containing number values (kind of ifnull or coallesce functions that are available in SQL).

You can do it by standard expressive XSLT way, with using variable and <xsl:choose>, or abuse built-in sum() function and do whole thing in one line.

Standard way:

<!– read the value –>
<xsl:variable name=”val”>
<xsl:choose>
<xsl:when test=”//number[1]”><xsl:value-of select=”//number[1]”/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!– print the value out –>
<xsl:value-of select=”$val“/>

 

Quick way:

<!– read and printout –>
<xsl:value-of select=”sum(//number[1])“/>

 

Both codes will print value of first node named number or zero if the node is not present.  Because it is a sum() function, it’s a good idea to limit nodeset only to first one, otherwise you will get a sum of all existing number nodes.

Btw. do you know the best XSLT reference out there ? No ? Look at ZVON XSLT reference.

 

Solr Pager 0.2.0 released

I’ve just published solr_pager a search component for Solr that should make paging easier. It’s main use should be by XSLT transformation (using XSLT writer), so one should not bother anymore with slow recursive XSLT hacks and only apply fast templates on paging list in search result.

Initial version 0.2.0 can be found on http://devel.dob.sk/solr_pager. Documentation is bundled 😉

I’ve tested it against development version of Solr 1.4, but I think it should works also with currently stable Solr 1.3 (If not let me know, I’ll try to fix it).

How it works:

After install Solr Pager and configuring Solr to use Pager component for results (see README file), one should simply pass pager parameter with number of pager starts that should be generated (pager=10) to search query and list of pager start will be returned in response, smth. like this:

<response>
 <lst name="pager">
 <lst name="pages">  <!-- list of all pages -->
   <int name="2">25</int>
   <int name="3">50</int>
   <int name="4">75</int> <!-- this is actual page -->
   <int name="5">100</int>
   <int name="6">125</int>
   <int name="7">150</int>
   <int name="8">175</int>
   <int name="9">200</int>
   <int name="10">225</int>
   <int name="11">250</int>
 </lst>
 <int name="prev">50</int>  <!-- previous page, with start = 50 -->
 <int name="next">100</int>  <!-- next page, with start = 75 -->
 <int name="last">1225</int> <!-- last page, with start = 1225 -->
 <int name="actual">4</int> <!-- actual page number -->
 <int name="count">49</int> <!-- count of all pages -->
 </lst>
</response>

There is also another parameter pager.pre that sets how many proceeding pager starts should be generated, one pager start will be generated for actual page and all other pages will be pager starts of pages following the actual page.

Name is position of the page starting from 1 and node value is parameter (document position) that should be passed back to solr as value for start parameter.

It’s simple component, so it should have no bugs (HA HA), but if found any plz. report them to me. Also if you have some interesting and usable feature or patch that could be added to Solr Pager, again,don’t be ashamed and let me know.

XSLT – copy node with attributes without childs

Simple solution for not-so-trivial problem of copying xml node with all its attributes, but without child nodes.

Without the last condition, solution is easy, one would use <xsl:copy-of>, but with it things are a bit harder, you should do smt. like:

<xsl:copy select="."> <!-- this copies element name -->
   <xsl:copy-of select="@*"/> <!-- this copies all its attributes -->
   ...what..ever..you..want..here...
</xsl:copy>

And thats all, seems easy but it took me some time to realize it (And I must do it myself, because google didn’t helped me !).