首页 > 解决方案 > XML Grouping 在表中添加数据

问题描述

我有来自数据库的 xml 数据。这些是一周中某些日子发生的事件。某一天可能有一个或多个事件。

我需要在按天排列的表格中显示事件信息。比如星期一作为标题,然后是一个包含事件信息的表格,然后是星期二作为标题,然后是星期二表格中的 2 个条目。

我意识到我可能需要根据工作日进行分组。我对xslt没有太多经验。我们该怎么做?浏览器不支持 xslt 2.0 所以我必须使用 xsl 1.0 。我必须解析 xml 并将其显示为 html。

<Events>
    <Event>
    <ActivityTypeName>Lab</ActivityTypeName>
    <WeekDay>Wednesday</WeekDay>
    <LocalDate>01/04/20</LocalDate>
    <Location>Eng. G29 Wet Lab</Location>
  </Event>
  <Event>
    <ActivityName>MAT427-MTRM061-DEN7601-DENM601-DENM600-DEN7600/B/Lec/02 [jt]</ActivityName>
    <ActivityTypeName>Lecture</ActivityTypeName>
    <WeekDay>Wednesday</WeekDay>  
     <LocalDate>02/04/20</LocalDate>
    <Location>Eng:2.16(42)</Location>
  </Event>
  <Event>
    <ActivityTypeName>Lecture</ActivityTypeName>
    <WeekDay>Thursday</WeekDay>
    <LocalDate>02/04/20</LocalDate>
    <Location>Eng:2.16(42)</Location>
  </Event>
  <Event>
    <ActivityTypeName>Seminar</ActivityTypeName>
    <WeekDay>Friday</WeekDay>
    <LocalDate>03/04/20</LocalDate>
    <Location>Graduate Ctr: GC102 (19)</Location>
  </Event>

标签: xmlxsltxslt-grouping

解决方案


让我们专注于 xsl 样式表,无论您在何处以及如何应用它。

假设您的事件按工作日和日期顺序流式传输,我将在工作日的第一个后续事件上创建一个密钥。这种方法使我们能够轻松地迭代那些“第一个”事件并创建独立的表。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>

    <!-- index first of sequentially occurring Event elements by WeekDay -->
    <xsl:key name="firstof_weekday_key" match="/Events/Event[(position() = 1) or (WeekDay != preceding-sibling::Event[1]/WeekDay)]" use="WeekDay"/>

    <xsl:template match="/Events">
        <html>
            <head>
                <style type="text/css">
                    .Table
                    {
                    display: table;
                    }
                    .Caption
                    {
                    display: table-caption;
                    text-align: center;
                    font-weight: bold;
                    font-size: larger;
                    }
                    .THead
                    {
                    display: table-header-group;
                    }
                    .TBody
                    {
                    display: table-row-group;
                    }
                    .Heading
                    {
                    display: table-row;
                    font-weight: bold;
                    text-align: center;
                    }
                    .Row
                    {
                    display: table-row;
                    }
                    .Cell
                    {
                    display: table-cell;
                    border: solid;
                    border-width: thin;
                    padding-left: 5px;
                    padding-right: 5px;
                    }
                </style>
            </head>
            <body>
                <!-- select first Event of WeekDay (which is included in the key) -->
                <xsl:apply-templates select="Event[count(. | key('firstof_weekday_key', WeekDay)) = count(key('firstof_weekday_key', WeekDay))]" mode="first"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="/Events/Event" mode="first">
        <div class="Table">
            <div class="Caption">
                <xsl:value-of select="WeekDay"/>
            </div>
            <div class="THead">
                <div class="Heading">
                    <div class="Cell">
                        <xsl:value-of select="'Activity'"/>
                    </div>
                    <div class="Cell">
                        <xsl:value-of select="'Location'"/>
                    </div>
                    <div class="Cell">
                        <xsl:value-of select="'Date'"/>
                    </div>
                </div>
            </div>
            <div class="TBody">
                <xsl:apply-templates select="." mode="data"/>
            </div>
        </div>
    </xsl:template>

    <xsl:template match="/Events/Event" mode="data">
        <div class="Row">
            <div class="Cell">
                <xsl:value-of select="ActivityTypeName"/>
            </div>
            <div class="Cell">
                <xsl:value-of select="Location"/>
            </div>
            <div class="Cell">
                <xsl:value-of select="LocalDate"/>
            </div>
        </div>
    
        <!-- get the next Event in the current WeekDay group -->
        <xsl:apply-templates select="following-sibling::Event[1][WeekDay = current()/WeekDay]" mode="data"/>
    </xsl:template>
</xsl:stylesheet>

此 xslt 会将您的事件转换为以下 html:

<html>
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    <style type="text/css">
                    .Table
                    {
                    display: table;
                    }
                    .Caption
                    {
                    display: table-caption;
                    text-align: center;
                    font-weight: bold;
                    font-size: larger;
                    }
                    .THead
                    {
                    display: table-header-group;
                    }
                    .TBody
                    {
                    display: table-row-group;
                    }
                    .Heading
                    {
                    display: table-row;
                    font-weight: bold;
                    text-align: center;
                    }
                    .Row
                    {
                    display: table-row;
                    }
                    .Cell
                    {
                    display: table-cell;
                    border: solid;
                    border-width: thin;
                    padding-left: 5px;
                    padding-right: 5px;
                    }
                </style>
  </head>
  <body>
    <div class="Table">
      <div class="Caption">Wednesday</div>
      <div class="THead">
        <div class="Heading">
          <div class="Cell">Activity</div>
          <div class="Cell">Location</div>
          <div class="Cell">Date</div>
        </div>
      </div>
      <div class="TBody">
        <div class="Row">
          <div class="Cell">Lab</div>
          <div class="Cell">Eng. G29 Wet Lab</div>
          <div class="Cell">01/04/20</div>
        </div>
        <div class="Row">
          <div class="Cell">Lecture</div>
          <div class="Cell">Eng:2.16(42)</div>
          <div class="Cell">02/04/20</div>
        </div>
      </div>
    </div>
    <div class="Table">
      <div class="Caption">Thursday</div>
      <div class="THead">
        <div class="Heading">
          <div class="Cell">Activity</div>
          <div class="Cell">Location</div>
          <div class="Cell">Date</div>
        </div>
      </div>
      <div class="TBody">
        <div class="Row">
          <div class="Cell">Lecture</div>
          <div class="Cell">Eng:2.16(42)</div>
          <div class="Cell">02/04/20</div>
        </div>
      </div>
    </div>
    <div class="Table">
      <div class="Caption">Friday</div>
      <div class="THead">
        <div class="Heading">
          <div class="Cell">Activity</div>
          <div class="Cell">Location</div>
          <div class="Cell">Date</div>
        </div>
      </div>
      <div class="TBody">
        <div class="Row">
          <div class="Cell">Seminar</div>
          <div class="Cell">Graduate Ctr: GC102 (19)</div>
          <div class="Cell">03/04/20</div>
        </div>
      </div>
    </div>
  </body>
</html>

推荐阅读