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?

Posted by codesforcoffee on Stack Overflow See other posts from Stack Overflow or by codesforcoffee
Published on 2012-11-20T19:53:49Z Indexed on 2012/11/20 23:01 UTC
Read the original article Hit count: 192

Filed under:
|
|
|
|

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:

enter image description here

© Stack Overflow or respective owner

Related posts about Xml

Related posts about xslt