moo moo
moo moo

Reputation: 9

How can I display the correct content in an XSLT table

I am trying to display the weather details from the XML into the table according to its date. eg. 12th Jun Sat it is 23-28 deg etc. However, I am not able to insert the details into the correct column. I have tried to use xsl:if and xsl:when but to no avail. I am not sure which function to use to point it to the correct day.

Sample output on how it should look like

XML File

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type = "text/xsl" href = "b2.xsl"?>

<forecast queryTime="30/7/2021 14:10:20" queryLocation=" Singapore ">
  <weather yyyymmdd="20210617">
    <year>2021</year>
    <month>6</month>
    <date>17</date>
    <dayOfWeek>Thu</dayOfWeek>
    <overall>Considerable clouds</overall>
    <overallCode>cloudy</overallCode>
    <highest>29</highest>
    <lowest>19</lowest>
  </weather>
  <weather yyyymmdd="20210612">
    <year>2021</year>
    <month>6</month>
    <date>12</date>
    <dayOfWeek>Sat</dayOfWeek>
    <overall>Cloudy with a thunderstorm</overall>
    <overallCode>thunderstorm</overallCode>
    <highest>28</highest>
    <lowest>23</lowest>
  </weather>
  <weather yyyymmdd="20210709">
    <year>2021</year>
    <month>7</month>
    <date>09</date>
    <dayOfWeek>Fri</dayOfWeek>
    <overall>A morning shower, then rain</overall>
    <overallCode>rain</overallCode>
    <highest>29</highest>
    <lowest>23</lowest>
  </weather>
  <weather yyyymmdd="20210601">
    <year>2021</year>
    <month>6</month>
    <date>01</date>
    <dayOfWeek>Tue</dayOfWeek>
    <overall>Partly sunny</overall>
    <overallCode>partlySunny</overallCode>
    <highest>31</highest>
    <lowest>28</lowest>
  </weather>
  <weather yyyymmdd="20210802">
    <year>2021</year>
    <month>8</month>
    <date>02</date>
    <dayOfWeek>Mon</dayOfWeek>
    <overall>Plenty of sunshine</overall>
    <overallCode>sunny</overallCode>
    <highest>35</highest>
    <lowest>24</lowest>
  </weather>
</forecast>
XSL File
<xsl:stylesheet version = "1.0" 
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">

    <xsl:template match = "/forecast">

        <html>

            <body>
                <h1>
                    <xsl:value-of select="@queryLocation"/>
                            [                    <xsl:value-of select="@queryTime"/>
]

                </h1>
                <table border="1" width="100%">
                    <tr id="days" bgcolor="#FFA500" align="center">
                        <th>Date</th>
                        <th>Mon</th>
                        <th>Tue</th>
                        <th>Wed</th>
                        <th>Thu</th>
                        <th>Fri</th>
                        <th>Sat</th>
                        <th>Sun</th>
                    </tr>

                    <xsl:for-each select = "weather">
                        <xsl:sort select="@yyyymmdd"/>
                        <tr>
                            <td bgcolor="#FFA500" align="center">
                                <xsl:value-of select = "date "/>

                                <xsl:variable name="month" select="month"/>
                                <xsl:choose>
                                    <xsl:when test="$month=1"> January</xsl:when>
                                    <xsl:when test="$month=2"> February</xsl:when>
                                    <xsl:when test="$month=3"> March</xsl:when>
                                    <xsl:when test="$month=4"> April</xsl:when>
                                    <xsl:when test="$month=5"> May</xsl:when>
                                    <xsl:when test="$month=6"> June</xsl:when>
                                    <xsl:when test="$month=7"> July</xsl:when>
                                    <xsl:when test="$month=8"> August</xsl:when>
                                    <xsl:when test="$month=9"> September</xsl:when>
                                    <xsl:when test="$month=10"> October</xsl:when>
                                    <xsl:when test="$month=11"> November</xsl:when>
                                    <xsl:when test="$month=12"> December</xsl:when>
                                </xsl:choose>
                            </td>

                            <tr>
                                <td>
                                    <xsl:for-each select = "weather"/>



                                    <xsl:value-of select = " lowest "/>
                                    <f>&#176;</f>
                                    <span>- </span>
                                    <xsl:value-of select = " highest "/>
                                    <f>&#176;</f>
                                </td>
                            </tr>

                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 220

Answers (2)

Professor Abronsius
Professor Abronsius

Reputation: 33813

With the given XML sample and modifying the XSL file like this:

<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
    <xsl:template match = "/forecast">

        <html>
            <head>
                <style>
                    table{border-collapse:collapse}
                    table td{border:1px solid black}
                    tr td{ 
                        height:10rem;
                        width:5rem 
                    }
                    tr td:first-of-type,
                    tr th:first-of-type{
                        width:50px;
                        max-width:100px
                    }
                    #days th{height:2rem;}
                    
                    .partlySunny,
                    .sunny{background:yellow;color:red}
                    .thunderstorm{background:grey;color:blue;}
                    .cloudy{background:whitesmoke;color:green}
                    .rain{background:aliceblue;color:pink}
                    
                </style>
            </head>
            <body>
                <h1>
                    <xsl:value-of select="@queryLocation"/> [ <xsl:value-of select="@queryTime"/> ]
                </h1>
                
                <table border="1" width="100%">
                    <tr id="days" bgcolor="#FFA500" align="center">
                        <th>Date</th>
                        <th>Mon</th>
                        <th>Tue</th>
                        <th>Wed</th>
                        <th>Thu</th>
                        <th>Fri</th>
                        <th>Sat</th>
                        <th>Sun</th>
                    </tr>

                    <xsl:for-each select="weather">
                        <xsl:sort select="@yyyymmdd"/>
                        <xsl:variable name="day" select="dayOfWeek"/>
                        
                        <tr>
                            <td bgcolor="#FFA500" align="center">
                                <xsl:value-of select = "date "/>

                                <xsl:variable name="month" select="month"/>
                                <xsl:choose>
                                    <xsl:when test="$month=1"> January</xsl:when>
                                    <xsl:when test="$month=2"> February</xsl:when>
                                    <xsl:when test="$month=3"> March</xsl:when>
                                    <xsl:when test="$month=4"> April</xsl:when>
                                    <xsl:when test="$month=5"> May</xsl:when>
                                    <xsl:when test="$month=6"> June</xsl:when>
                                    <xsl:when test="$month=7"> July</xsl:when>
                                    <xsl:when test="$month=8"> August</xsl:when>
                                    <xsl:when test="$month=9"> September</xsl:when>
                                    <xsl:when test="$month=10"> October</xsl:when>
                                    <xsl:when test="$month=11"> November</xsl:when>
                                    <xsl:when test="$month=12"> December</xsl:when>
                                </xsl:choose>
                            </td>
                            
                            
                            <!--
                                
                                I am sure that this can be done in a considerably more refined manner
                                but it is so long since I last used XSL I have forgotten much of what 
                                I once knew.
                                
                                You can sort of emulate an array and iterate through it so an array of
                                day names might work with a for-each loop...?
                            -->
                            <xsl:choose>
                                <xsl:when test="$day='Mon'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>    
                                <xsl:when test="$day='Tue'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>
                                <xsl:when test="$day='Wed'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>
                                <xsl:when test="$day='Thu'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>
                                <xsl:when test="$day='Fri'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>
                                <xsl:when test="$day='Sat'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                            </xsl:choose>
                            
                            
                            <xsl:choose>
                                <xsl:when test="$day='Sun'">
                                    <td>
                                        <xsl:attribute name="class"><xsl:value-of select="overallCode"/></xsl:attribute>
                                        <xsl:value-of select="overall"/>
                                        <xsl:value-of select="lowest"/><f>&#176;</f><span> - </span><xsl:value-of select="highest"/><f>&#176;</f>
                                    </td>
                                </xsl:when> 
                                <xsl:otherwise>
                                    <td></td>
                                </xsl:otherwise>
                                
                            </xsl:choose>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

I know it is crude - I simply cannot remember much of the ways and means of doing things in XSL as it is so long since I used it.

Which yields: resultant display

Upvotes: 1

Vasyl Krupa
Vasyl Krupa

Reputation: 211

to place weather information in correct cell you need to add preceding and following cells inside a row.

To do so in 1st version of XSLT you can create a variable with days of the week and count preceding and following siblings. I added changes XSLT code below. Please let me know if it works for you.

<xsl:stylesheet version = "1.0"
            xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="days">
    <week>
        <day>Mon</day>
        <day>Tue</day>
        <day>Wed</day>
        <day>Thu</day>
        <day>Fri</day>
        <day>Sat</day>
        <day>Sun</day>
    </week>
</xsl:variable>

<xsl:template match = "/forecast">
    <html>
        <body>
            <h1>
                <xsl:value-of select="@queryLocation"/>
                <xsl:text>[</xsl:text>
                <xsl:value-of select="@queryTime"/>
                <xsl:text>]</xsl:text>
            </h1>
            <table border="1" width="100%">
                <tr id="days" bgcolor="#FFA500" align="center">
                    <th>Date</th>

                    <xsl:for-each select="$days/descendant::day">
                        <th>
                            <xsl:value-of select="."/>
                        </th>
                    </xsl:for-each>
                </tr>

                <xsl:for-each select = "weather">
                    <xsl:sort select="@yyyymmdd"/>
                    <xsl:variable name="currentDayOfWeek" select="dayOfWeek"/>

                    <tr>
                        <td bgcolor="#FFA500" align="center">
                            <xsl:value-of select = "date "/>
                            <xsl:variable name="month" select="month"/>
                            <xsl:choose>
                                <xsl:when test="$month=1"> January</xsl:when>
                                <xsl:when test="$month=2"> February</xsl:when>
                                <xsl:when test="$month=3"> March</xsl:when>
                                <xsl:when test="$month=4"> April</xsl:when>
                                <xsl:when test="$month=5"> May</xsl:when>
                                <xsl:when test="$month=6"> June</xsl:when>
                                <xsl:when test="$month=7"> July</xsl:when>
                                <xsl:when test="$month=8"> August</xsl:when>
                                <xsl:when test="$month=9"> September</xsl:when>
                                <xsl:when test="$month=10"> October</xsl:when>
                                <xsl:when test="$month=11"> November</xsl:when>
                                <xsl:when test="$month=12"> December</xsl:when>
                            </xsl:choose>
                        </td>
                        <xsl:for-each select="$days/descendant::day[normalize-space(.) = normalize-space($currentDayOfWeek)]/preceding-sibling::day">
                            <td></td>
                        </xsl:for-each>
                        <td>
                            <xsl:value-of select = " lowest "/>
                            <f>&#176;</f>
                            <span>- </span>
                            <xsl:value-of select = " highest "/>
                            <f>&#176;</f>
                        </td>
                        <xsl:for-each select="$days/descendant::day[normalize-space(.) = normalize-space($currentDayOfWeek)]/following-sibling::day">
                            <td></td>
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>

Upvotes: 0

Related Questions