With XSLT, how can I add a node inside of a for loop? I want to use this if-test with an array, and the element I'd like to search for in the array is returned by a template call inside the for loop...

Unanswered With XSLT, how can I add a node inside of a for loop? I want to use this if-test with an array, and the element I'd like to search for in the array is returned by a template call inside the for loop...

  • Wednesday, November 21, 2012 12:58 AM
     
      Has Code

    I think this simple example might ask the question a lot more clearly.

    I have an input file with multiple products.  There are  different types of product (2 types with 2 product IDs is fine enough for this example), but the input will have many more.

    I only want to output the info for the first product of each type that I encounter in the for each Product loop.  (I'm outputting info for the lowest priced product, so the first one will be the lowest price because I sort by Rate 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 have a variable for the IDArray, and I want to check if each product inside the for each product loop has an ID that is already in that IDArray - if not, continue, if it is already in the array, skip everything and just loop to the next.

    I couldn't figure out how to get the child element to be a node from IDArray with the value of each CurrentID.  It keeps adding that value as a node to CurrentID which is only in the scope of each product, not the whole product group.  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="Product/Rate"/>
             <xsl:variable name="IDarray">
             <xsl:for-each select="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>
    
    
       

    An input would look like this:

     <ProductGroup>
          <Product>
            <ProductCode>
               5155
            </ProductCode>
            <ProductName>
               House
            </ProductName>
            <Rate>
               3.99
            </Rate>
            </Product>
            <Product>
            <ProductCode>
               5158
            </ProductCode>
            <ProductName>
               House
            </ProductName>
            <Rate>
               4.99
            </Rate>
            </Product>
           </ProductGroup>
                <ProductGroup>
          <Product>
            <ProductCode>
               2058
            </ProductCode>
            <ProductName>
               House
            </ProductName>
            <Rate>
               2.99
            </Rate>
            </Product>
            <Product>
            <ProductCode>
               2055
            </ProductCode>
            <ProductName>
               House
            </ProductName>
            <Rate>
               7.99
            </Rate>
            </Product>
           </ProductGroup>




    Output would be this for only that simple input file:

    <List>
     <Product ID=5>
      <prod_name>
        House
      </prod_name>
      <rate>
        3.99
      </rate>
     </Product>
     <Product ID=2>
      <prod_name>
        House
      </prod_name>
      <rate>
        2.99
      </rate>
     </Product>
    </List>

    Implementing a Muenchian grouping is tough here because my actual dataset is huge.  I made it simple to ask a question.  If I can just get that array method working, the rest of my huge project will work.

    Thanks so much!  I know some of the awesome programmers here can help! :)

    -Holly

All Replies

  • Wednesday, November 21, 2012 6:04 PM
     
     

    Actually, my problem is a whole lot more complicated, so I tried to make a simple example that I could ask a question with.

    The reality is that I'm translating it for another company that has their own IDs I have to assign based on 3 or 4 parameters. So doing a substring won't actually work.

    I really needed to figure out the way where I'd add each product ID that I assign to an array so the next time I come across that type, I just skip that loop because that type of product was already done. It just has to be the first one I encounter because I've already sorted it so that the first is the best.

    Any idea how to make that node-set method work? I really appreciate the help!


  • Friday, November 23, 2012 8:03 AM
    Moderator
     
     

    Hi codes,

    I moved this thread to a dedicated forum for better support.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

  • Monday, November 26, 2012 5:31 PM
     
     

    Hi Mike,

    Where can I find the place you moved it to, so I can see if anyone answered? :)

    Thanks!

    -Holly

  • Tuesday, November 27, 2012 2:26 AM
    Moderator
     
     

    Hi Holly,

    Your thread is in the right forum now.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.