tags:

views:

35

answers:

1

I have a problem. I get the data from xml then transform it with xslt.

Let us say I have a xml file:

<?xml version="1.0"?> 
 <root> 
   <row id="1" fname="Dan" lname="Wahlin"> 
    <address type="home"> 
       <street>1234 Anywhere St.</street> 
       <city>AnyTown</city> 
       <zip>85789</zip> 
     </address> 
     <address type="business"> 
       <street>1234 LottaWork Ave.</street> 
       <city>AnyTown</city> 
       <zip>85786</zip> 
     </address> 
  </row> 
   <row id="2" fname="Elaine" lname="Wahlin"> 
    <address type="home"> 
      <street>1234 Anywhere St.</street> 
      <city>AnyTown</city> 
       <zip>85789</zip> 
     </address> 
    <address type="business"> 
      <street>1233 Books Way</street> 
       <city>AnyTown</city> 
       <zip>85784</zip> 
    </address> 
  </row> 
 </root> 

And this stylesheet:

<?xml version="1.0" ?>   
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
   version="1.0">   
<xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="no"/>  
   <xsl:template match="/"> 
     <root>  
        <xsl:apply-templates/>  
      </root>  
    </xsl:template> 
    <xsl:template match="row">  
          <row>  
            <xsl:attribute name="id">  
                    <xsl:value-of select="id"/>  
               </xsl:attribute>  
                <xsl:attribute name="fname">  
                     <xsl:value-of select="name/fname"/>  
                </xsl:attribute>  
                <xsl:attribute name="lname">  
                     <xsl:value-of select="name/lname"/>  
              </xsl:attribute>  
              <xsl:for-each select="address">  
                   <xsl:copy-of select="."/>  
               </xsl:for-each>           </row>  
      </xsl:template>  
 </xsl:stylesheet>

How can limit this to 3 records, then after 3 records it create a tr tag?

For example:

<table> 
<tr> 
  <td>Address1</td> 
  <td>Address2</td> 
  <td>Address3</td> 
</tr> 
<tr> 
   <td>Address4</td> 
   <td>Address5</td> 
   <td>Address6</td> 
</tr> 
</table>
A: 

Instead of:

<xsl:for-each select="address">  
<xsl:copy-of select="."/>  
</xsl:for-each>

You should have something like this:

<xsl:for-each select="address">
<xsl:if test="position() mod 3 = 1">
<tr>
<xsl:call-template name="printAddress">
<xsl:with-param name="address" select="."/>
</xsl:call-template>
<xsl:call-template name="printAddress">
<xsl:with-param name="address" select="following-sibling::*[position() = 1]"/>
</xsl:call-template>
<xsl:call-template name="printAddress">
<xsl:with-param name="address" select="following-sibling::*[position() = 2]"/>
</xsl:call-template>
</tr>
</xsl:if>
</xsl:for-each>

And of course you have to have template printAddress somewhere.

This should give you an idea on how to solve it. The point is to process every n-th item (chosen by position() mod n) and explicitly process n following items at once (chosen by following-sibling::*[position() = x]), wrapping them in tr. Notice that it is important to compare mod result with 1, since position starts counting from 1.

calavera.info
what is "galleryItem"? is this souhld exist in my stylesheet?
This is just a copy-paste from my own template which creates 3 column table of images from a simple list, which is the same situation as you have. As I wrote, it should just give you an idea of how to do it, you should be able to apply it for your situation yourself.
calavera.info
@calavera.info: It is quite confusing to just post a stylesheet for totally different input. The least you could do would be to adapt your technique for the given input data.
Jim Garrison
@Jim Garrison: You can see, that adapting it to his "totally different input" means changing 3 names. crisgomez asked a very good question, which can be tricky even to experienced developer, so it deserves an answer. But I also suspect him of not having much interest in the xsl or the community. The point was to provide a valuable answer while not doing his homework instead of him (in my work time, by the way).
calavera.info