Skip to content

Instantly share code, notes, and snippets.

@clodio
Created May 11, 2015 07:17
Show Gist options
  • Save clodio/a8aad674829585ff0e57 to your computer and use it in GitHub Desktop.
Save clodio/a8aad674829585ff0e57 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<!--
XSLT permettant de changer le format de sortie solr pour faire de la pagination au format JSON
TODO : tester en charge pour valider les performances
*** Installation
Déposer ce ficher json_paginate.xsl dans le répertoire conf/xslt de l'index solr concerné
Installer les extensions permettant de faire des XPATH 2.0
Déposer dans le répertoire solr lib/ext les fichiers jar de http://www.saxonica.com/download/SaxonPE9-6-0-5J.zip
*** Utilisation
Appeler les url de solr en passant les arguments suivants
wt=xstl
tr=json_paginate.xsl
p_url=url permettant de générer la pagination (toute l'url excepté les parametres start_index et count
Exemple : http://localhost:8983/solr/techproducts/select?q=*&fq=price:0&wt=xslt&tr=json_paginate&start=10&p_url=http://api.laposte.fr/example/v1/techproducts?price=0
*** Configuration
configurer pour la production la mis en cache du fichier de configuration xslt : dans solr.config, mettre une valeur
<int name="xsltCacheLifetimeSeconds">360000</int>
*** Sortie
{ "data":[liste des ressource],
"paginate": {
"total_found": nombre d'éléments retournés
"prev": lien de pagination page précedente
"next": lien de pagination page suivante
}
}
-->
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no" media-type="application/json"/>
<xsl:variable name="numFound" select="response/result/@numFound"/>
<xsl:variable name="start" select="response/result/@start"/>
<xsl:variable name="nbDocsReturned" select="count(response/result/doc)"/>
<xsl:variable name="nextStartIndex" select="$start+1 + $nbDocsReturned +1"/>
<xsl:variable name="prevStartIndex" select="max((1, $start+1 - $nbDocsReturned))"/>
<xsl:variable name="paginateURL" select="response/lst/lst/str[@name='p_url']/text()"/>
<xsl:template match='/'>
<xsl:text>{"data":[</xsl:text>
<xsl:apply-templates select="response/result/doc"/>
<xsl:text>],</xsl:text>
<xsl:text>"paging":{"total_results":</xsl:text><xsl:value-of select="response/result/@numFound"/>
<xsl:if test="($start) &gt; 0">
<xsl:text>,"prev":"</xsl:text><xsl:value-of select="$paginateURL"/>
<xsl:text><![CDATA[&start_index=]]></xsl:text><xsl:value-of select="$prevStartIndex"/>
<xsl:text><![CDATA[&count=]]></xsl:text><xsl:value-of select="$nbDocsReturned"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:if test="($nbDocsReturned+$start) &lt; $numFound">
<xsl:text>,"next":"</xsl:text><xsl:value-of select="$paginateURL"/>
<xsl:text><![CDATA[&start_index=]]></xsl:text><xsl:value-of select="$nextStartIndex"/>
<xsl:text><![CDATA[&count=]]></xsl:text><xsl:value-of select="$nbDocsReturned"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}}</xsl:text>
</xsl:template>
<xsl:template match="doc">
<xsl:variable name="pos" select="position()"/>
<xsl:if test="position() &gt; 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text>{</xsl:text>
<xsl:apply-templates>
<xsl:with-param name="pos"><xsl:value-of select="$pos"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="doc/*">
<xsl:if test="position() &gt; 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text>"</xsl:text><xsl:value-of select="@name"/><xsl:text>":</xsl:text>
<xsl:choose>
<!-- if decimal, do not add quotes -->
<xsl:when test=". castable as xs:decimal">
<xsl:value-of select="."/>
</xsl:when>
<!-- if integer, do not add quotes -->
<xsl:when test=". castable as xs:integer">
<xsl:value-of select="."/>
</xsl:when>
<!-- if boolean, do not add quotes -->
<xsl:when test=". castable as xs:boolean">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:text>"</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text>
</xsl:otherwise>
</xsl:choose>
<!-- personnalisatio des champs adaptée au schéma -->
<!--
<xsl:choose>
<xsl:when test="@name='price'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:when test="@name='inStock'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:when test="@name='popularity'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:when test="@name='_version_'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:text>"</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text>
</xsl:otherwise>
</xsl:choose>
-->
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment