如何在 XSLT 表中显示正确的内容

Posted

技术标签:

【中文标题】如何在 XSLT 表中显示正确的内容【英文标题】:How can I display the correct content in an XSLT table 【发布时间】:2021-12-14 13:00:28 【问题描述】:

我正在尝试根据日期将 XML 中的天气详细信息显示到表格中。例如。 6 月 12 日星期六是 23-28 度等。但是,我无法将详细信息插入正确的列。我曾尝试使用 xsl:if 和 xsl:when 但无济于事。我不确定使用哪个函数将其指向正确的日期。

Sample output on how it should look like

XML 文件

<?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 文件
<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" >
                    <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>

【问题讨论】:

您的 XSL 嵌套了 tr 标签 这个问题(或者更确切地说是作业)之前提出过:***.com/q/67651265/3016153 当时不是很清楚,现在仍然不是。但是您可能会在这些 cmets 中找到一些指针。 【参考方案1】:

要将天气信息放置在正确的单元格中,您需要在一行中添加前面和后面的单元格。

为此,您可以在 XSLT 的第一个版本中创建一个包含星期几的变量,并计算前后兄弟姐妹的数量。我在下面添加了更改 XSLT 代码。请让我知道它是否适合您。

<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" >
                <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>

【讨论】:

我认为这不会产生他们想要的结果,但我不确定他们是否知道自己想要什么。在任何情况下,您的样式表都会显示version = "1.0",但它会在 XSLT 1.0 处理器上出错。 没有成功,但感谢您的宝贵时间!【参考方案2】:

使用给定的 XML 示例并像这样修改 XSL 文件:

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

        <html>
            <head>
                <style>
                    tableborder-collapse:collapse
                    table tdborder: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 thheight:2rem;
                    
                    .partlySunny,
                    .sunnybackground:yellow;color:red
                    .thunderstormbackground:grey;color:blue;
                    .cloudybackground:whitesmoke;color:green
                    .rainbackground:aliceblue;color:pink
                    
                </style>
            </head>
            <body>
                <h1>
                    <xsl:value-of select="@queryLocation"/> [ <xsl:value-of select="@queryTime"/> ]
                </h1>
                
                <table border="1" >
                    <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>

我知道它很粗糙 - 我根本不记得在 XSL 中做事的很多方式和方法,因为我已经很久没有使用它了。

产生:

【讨论】:

非常感谢!坚持了这么久!非常感谢! 不客气,但我有 99% 的把握肯定有比这更清洁的方法......如果我弄清楚了,我会更新上面的

以上是关于如何在 XSLT 表中显示正确的内容的主要内容,如果未能解决你的问题,请参考以下文章

XSLT:如何在 html 结果中正确应用 css 类

如何在XSLT中正确编辑节点值

如何在特定节点的 XSLT 中显示属性?

如何使用 JavaScript 转换 XML 和 XSLT?

如何使用 XSLT 显示 XSD 验证的 XML

Firefox 不再解释 XSLT-1.0