Comment utiliser XSLT pour créer des valeurs distinctes
J'ai XML comme ceci:
<items>
<item>
<products>
<product>laptop</product>
<product>charger</product>
</products>
</item>
<item>
<products>
<product>laptop</product>
<product>headphones</product>
</products>
</item>
</items>
Je veux qu'il sorte comme
laptop charger headphones
J'essayais d'utiliser distinct-values()
mais je suppose que je fais quelque chose de mal. Quelqu'un peut-il me dire comment y parvenir en utilisant distinct-values()
? Grâce.
<xsl:template match="/">
<xsl:for-each select="//products/product/text()">
<li>
<xsl:value-of select="distinct-values(.)"/>
</li>
</xsl:for-each>
</xsl:template>
Mais cela me donne une sortie comme ceci:
<li>laptop</li>
<li>charger</li>
<li>laptop></li>
<li>headphones</li>
5 réponses
Une solutionXSLT 1.0 qui utilise key
et la fonction generate-id()
pour obtenir des valeurs distinctes:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="product" match="/items/item/products/product/text()" use="." />
<xsl:template match="/">
<xsl:for-each select="/items/item/products/product/text()[generate-id()
= generate-id(key('product',.)[1])]">
<li>
<xsl:value-of select="."/>
</li>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Voici une solution XSLT 1.0 que j'ai utilisée dans le passé, je pense qu'elle est plus succincte (et lisible) que d'utiliser la fonction generate-id()
.
<xsl:template match="/">
<ul>
<xsl:for-each select="//products/product[not(.=preceding::*)]">
<li>
<xsl:value-of select="."/>
</li>
</xsl:for-each>
</ul>
</xsl:template>
Renvoie:
<ul xmlns="http://www.w3.org/1999/xhtml">
<li>laptop</li>
<li>charger</li>
<li>headphones</li>
</ul>
Vous ne voulez pas de sortie "(distinct-values)", mais plutôt "for-each (distinct-values)":
<xsl:template match="/">
<xsl:for-each select="distinct-values(/items/item/products/product/text())">
<li>
<xsl:value-of select="."/>
</li>
</xsl:for-each>
</xsl:template>
Je suis arrivé à ce problème en travaillant avec un rendu Sitecore XSL. L'approche qui utilisait key () et l'approche qui utilisait l'axe précédent fonctionnaient très lentement. J'ai fini par utiliser une méthode similaire à key () mais qui ne nécessitait pas d'utiliser key(). Il fonctionne très rapidement.
<xsl:variable name="prods" select="items/item/products/product" />
<xsl:for-each select="$prods">
<xsl:if test="generate-id() = generate-id($prods[. = current()][1])">
<xsl:value-of select="." />
<br />
</xsl:if>
</xsl:for-each>