How to use XSLT to create individual values

I have this XML:

<items> <item> <products> <product>laptop</product> <product>charger</product> </products> </item> <item> <products> <product>laptop</product> <product>headphones</product> </products> </item> </items> 

I want it displayed as

 laptop
 charger
 headphones

I tried to use distinct-values() , but I think I'm doing something wrong. Can someone tell me how to achieve this using distinct-values() ? Thank.

 <xsl:template match="/"> <xsl:for-each select="//products/product/text()"> <li> <xsl:value-of select="distinct-values(.)"/> </li> </xsl:for-each> </xsl:template> 

but it gives me the output as follows:

 <li>laptop</li> <li>charger</li> <li>laptop></li> <li>headphones</li> 
+51
xslt
Feb 18 '10 at 19:27
source share
6 answers

An XSLT 1.0 solution that uses the key and generate-id() functions to get various values:

 <?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> 
+51
Feb 19 2018-10-19T00
source share

Here's the XSLT 1.0 solution I used in the past, I find it more concise (and readable) than using the generate-id() function.

  <xsl:template match="/"> <ul> <xsl:for-each select="//products/product[not(.=preceding::*)]"> <li> <xsl:value-of select="."/> </li> </xsl:for-each> </ul> </xsl:template> 

Return:

 <ul xmlns="http://www.w3.org/1999/xhtml"> <li>laptop</li> <li>charger</li> <li>headphones</li> </ul> 
+47
Sep 19 '13 at 4:16
source share

You do not want to "output (separate values)", but rather "for each (separate 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> 
+17
Feb 18 '10 at 19:46
source share

I ran into this problem when working with Sitecore XSL rendering. Both approaches that used key () and the approach that used the previous axis were very slow. I ended up using a method similar to key (), but this does not require the use of key (). It works very fast.

 <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> 
+13
Apr 02 '14 at 16:00
source share

distinct-values(//product/text())

+8
Feb 18 '10 at 19:30
source share

I found that you can do what you want with XSLT 1.0 without the generate-id() and key() functions.

Here is a Microsoft-specific solution (.NET class XslCompiledTransform , or MSXSLT.exe or Microsoft platfocm COM objects).

This is based on this answer . You can copy the sorted node into a variable ( $sorted-products in the stylesheet below) and then convert it into a set of nodes using the ms:node-set function. Then you can for-each second time after sorting a set of nodes:

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ms="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ms"> <xsl:output method="html" indent="yes" /> <xsl:template match="/"> <xsl:variable name="sorted-products"> <xsl:for-each select="//products/product"> <xsl:sort select="text()" /> <xsl:copy-of select=".|@*" /> </xsl:for-each> </xsl:variable> <xsl:variable name="products" select="ms:node-set($sorted-products)/product" /> <xsl:for-each select="$products"> <xsl:variable name='previous-position' select="position()-1" /> <xsl:if test="normalize-space($products[$previous-position]) != normalize-space(./text())"> <li> <xsl:value-of select="./text()" /> </li> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

exit:

 <li>charger</li> <li>headphones</li> <li>laptop</li> 

You can try it on the online playground .

0
Apr 26 '19 at 11:23
source share



All Articles