With XSLT, how can I use this if-test with an array, when search element is returned by a template call inside the for loop?
- by codesforcoffee
I think this simple example might ask the question a lot more clearly.
I have an input file with multiple products. There are 10 types of product (2 product IDs is fine enough for this example), but the input will have 200 products, and I only want to output the info for the first product of each type. (Output info for the lowest priced one, so the first one will be the lowest price because I sort by Price first.)
So I want to read in each product, but only output the product's info if I haven't already output a product with that same ID.
I couldn't figure out how to get the processID template to return a value that I need to do my if-check on, that uses parameters from inside the for-each Product loop -then properly close the if tag in the right place so it won't output the open Product tag unless it passes the if test. I know the following code does not work, but it illustrates the idea and gives me a place to start:
<?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" cdata-section-elements="prod_name adv_notes"/>
<xsl:template match="/">
<List>
<xsl:for-each select="ProductGroup">
<xsl:sort select="ActiveProducts/Product/Rate"/>
<xsl:variable name="IDarray">
<xsl:for-each select="ActiveProducts/Product">
<xsl:variable name="CurrentID">
<xsl:call-template name="processID">
<xsl:with-param name="ProductCode" select="ProductCode" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="not(contains($IDarray, $CurrentID))">
<child elem="{@elem}">
<xsl:select value-of="$CurrentID" />
</child>
<Product>
<xsl:attribute name="ID">
<xsl:select value-of="$CurrentID" />
</xsl:attribute>
<prod_name>
<xsl:value-of select="../ProductName"/>
</prod_name>
<rate>
<xsl:value-of select="../Rate"/>
</rate>
</Product>
</xsl:if>
</xsl:for-each>
</xsl:variable>
</xsl:for-each>
</List>
</xsl:template>
<xsl:template name="processID">
<xsl:param name="ProductCode"/>
<xsl:choose>
<xsl:when test="starts-with($ProductCode, '515')">5</xsl:when>
<xsl:when test="starts-with($ProductCode, '205')">2</xsl:when>
</xsl:choose>
</xsl:template>
Thanks so much in advance, I know some of the awesome programmers here can help! :)
-Holly
An input would look like this:
<ProductGroup>
<ActiveProducts>
<Product>
<ProductCode>
5155
</ProductCode>
<ProductName>
House
</ProductName>
<Rate>
3.99
</Rate>
</Product>
<Product>
<ProductCode>
5158
</ProductCode>
<ProductName>
House
</ProductName>
<Rate>
4.99
</Rate>
</Product>
</ActiveProducts>
</ProductGroup>
<ProductGroup>
<ActiveProducts>
<Product>
<ProductCode>
2058
</ProductCode>
<ProductName>
House
</ProductName>
<Rate>
2.99
</Rate>
</Product>
<Product>
<ProductCode>
2055
</ProductCode>
<ProductName>
House
</ProductName>
<Rate>
7.99
</Rate>
</Product>
</ActiveProducts>
</ProductGroup>
200 of those with different attributes. I have the translation working, just needed to add that array and if statement somehow.
Output would be this for only that simple input file: