Search code examples
xmlxsltxpathxslt-2.0ecrion

Write xsl or xpath syntax to repeat a table using Ecrion Design Studio Publisher or otherwise


I am using Ecrion's Design Studio Publisher to design a template using a xml source. I am trying to achieve the following using xpath or xsl and am not sure how

For eg: i have the following xml file

<?xml version="1.0" encoding="utf-8"?>
<DOCUMENT>  
  <PLAN>
    <PLANNAME>Plan 1</PLANNAME> 
    <BENEFITS>
        <INSURANCE>
            <CATEGORY ID="1">
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 1</PREMIUM>
                <INNETWORK>In network 1</INNETWORK>
        </INSURANCE>    
        <INSURANCE>
            <CATEGORY ID="2">
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 4</PREMIUM>
                <INNETWORK>In network 4</INNETWORK>
        </INSURANCE>
    </BENEFITS>
  </PLAN>  
  <PLAN>
    <PLANNAME>Plan 2</PLANNAME> 
    <BENEFITS>
        <INSURANCE>
            <CATEGORY ID="1">
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 2</PREMIUM>
                <INNETWORK>In network 2</INNETWORK>
        </INSURANCE>    
        <INSURANCE>
            <CATEGORY ID="2">
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 5</PREMIUM>
                <INNETWORK>In network 5</INNETWORK>
        </INSURANCE>
    </BENEFITS>
  </PLAN>  
  <PLAN>
    <PLANNAME>Plan 3</PLANNAME> 
    <BENEFITS>
        <INSURANCE>
            <CATEGORY ID="1">
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 3</PREMIUM>
                <INNETWORK>In network 3</INNETWORK>
        </INSURANCE>    
        <INSURANCE>
            <CATEGORY ID="2">
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 6</PREMIUM>
                <INNETWORK>In network 6</INNETWORK>
        </INSURANCE>
    </BENEFITS>
  </PLAN>  
  </DOCUMENT>

and i want to display the above in a table format like below

    <table style="width: 252px;" border="0" cellspacing="0" cellpadding="0"><colgroup><col span="3" width="84" /> </colgroup>
<tbody>
<tr>
<td class="xl65" style="text-align: center;" width="84" height="21">Plan 1</td>
<td class="xl65" style="text-align: center;" width="84">Plan 2</td>
<td class="xl65" style="text-align: center;" width="84">Plan 3</td>
</tr>
<tr>
<td class="xl66" style="text-align: center;" colspan="3" height="21">Insurance 1</td>
</tr>
<tr>
<td class="xl65" style="text-align: center;" height="21">Premium 1</td>
<td class="xl65" style="text-align: center;">Premium 2</td>
<td class="xl65" style="text-align: center;">Premium 3</td>
</tr>
<tr>
<td class="xl65" style="text-align: center;" height="21">In network 1</td>
<td class="xl65" style="text-align: center;">In network 2</td>
<td class="xl65" style="text-align: center;">In network 3</td>
</tr>
<tr>
<td class="xl66" style="text-align: center;" colspan="3" height="21">Insurance 2</td>
</tr>
<tr>
<td class="xl65" style="text-align: center;" height="21">Premium 4</td>
<td class="xl65" style="text-align: center;">Premium 5</td>
<td class="xl65" style="text-align: center;">Premium 6</td>
</tr>
<tr>
<td class="xl65" style="text-align: center;" height="21">In network 4</td>
<td class="xl65" style="text-align: center;">In network 5</td>
<td class="xl65" style="text-align: center;">In network 6</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>

If above table doesn't work, please apologize. It should look something like this

-------------------------------------------------
Plan 1       |       Plan 2       |       Plan 3
-------------------------------------------------
                  Insurance 1
-------------------------------------------------
Premium 1    |     Premium 2      |   Premium 3
-------------------------------------------------
In network 1 | In network 2       | In network 3
-------------------------------------------------
                  Insurance 2
-------------------------------------------------
Premium 4    |   Premium 5        |   Premium 6
-------------------------------------------------
In network 4 | In network 5       | In network 6
------------------------------------------------- 

Solution

  • Given a well-formed input:

    <DOCUMENT>  
      <PLAN>
        <PLANNAME>Plan 1</PLANNAME> 
        <BENEFITS>
            <INSURANCE>
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 1</PREMIUM>
                <INNETWORK>In network 1</INNETWORK>
            </INSURANCE>    
            <INSURANCE>
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 4</PREMIUM>
                <INNETWORK>In network 4</INNETWORK>
            </INSURANCE>
        </BENEFITS>
      </PLAN>  
      <PLAN>
        <PLANNAME>Plan 2</PLANNAME> 
        <BENEFITS>
            <INSURANCE>
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 2</PREMIUM>
                <INNETWORK>In network 2</INNETWORK>
            </INSURANCE>    
            <INSURANCE>
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 5</PREMIUM>
                <INNETWORK>In network 5</INNETWORK>
            </INSURANCE>
        </BENEFITS>
      </PLAN>  
      <PLAN>
        <PLANNAME>Plan 3</PLANNAME> 
        <BENEFITS>
            <INSURANCE>
                <LABEL>Insurance 1</LABEL>
                <PREMIUM>Premium 3</PREMIUM>
                <INNETWORK>In network 3</INNETWORK>
            </INSURANCE>    
            <INSURANCE>
                <LABEL>Insurance 2</LABEL>
                <PREMIUM>Premium 6</PREMIUM>
                <INNETWORK>In network 6</INNETWORK>
            </INSURANCE>
        </BENEFITS>
      </PLAN>  
    </DOCUMENT>
    

    the following stylesheet:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:variable name="cols" select="DOCUMENT/PLAN" />
        <xsl:variable name="rows" select="DOCUMENT/PLAN[1]/BENEFITS/INSURANCE" />
        <table>
            <thead>
                <tr>    
                    <xsl:for-each select="$cols">
                        <th><xsl:value-of select="PLANNAME"/></th>  
                    </xsl:for-each>
                </tr>
            </thead>
            <tbody>
                <xsl:for-each select="$rows">   
                    <xsl:variable name="rownum" select="position()" />
                    <tr>
                        <th colspan="{count($cols)}"><xsl:value-of select="LABEL"/></th>    
                    </tr>
                    <tr>
                        <xsl:for-each select="$cols">   
                            <td><xsl:value-of select="BENEFITS/INSURANCE[$rownum]/PREMIUM"/></td>   
                        </xsl:for-each>
                    </tr>
                    <tr>
                        <xsl:for-each select="$cols">   
                            <td><xsl:value-of select="BENEFITS/INSURANCE[$rownum]/INNETWORK"/></td> 
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </tbody>
        </table>
    </xsl:template>
    
    </xsl:stylesheet>
    

    will produce the following result:

    <?xml version="1.0" encoding="UTF-8"?>
    <table>
       <thead>
          <tr>
             <th>Plan 1</th>
             <th>Plan 2</th>
             <th>Plan 3</th>
          </tr>
       </thead>
       <tbody>
          <tr>
             <th colspan="3">Insurance 1</th>
          </tr>
          <tr>
             <td>Premium 1</td>
             <td>Premium 2</td>
             <td>Premium 3</td>
          </tr>
          <tr>
             <td>In network 1</td>
             <td>In network 2</td>
             <td>In network 3</td>
          </tr>
          <tr>
             <th colspan="3">Insurance 2</th>
          </tr>
          <tr>
             <td>Premium 4</td>
             <td>Premium 5</td>
             <td>Premium 6</td>
          </tr>
          <tr>
             <td>In network 4</td>
             <td>In network 5</td>
             <td>In network 6</td>
          </tr>
       </tbody>
    </table>
    

    rendered as:

    enter image description here