XML Группировка для добавления данных в таблицу - PullRequest
0 голосов
/ 04 августа 2020

У меня есть xml данных из базы. Это события, происходящие в определенные дни недели. В конкретный день может быть одно или несколько событий.

Мне нужно отобразить информацию о событиях в таблице, упорядоченной по дням. Например, понедельник в качестве заголовка, затем таблица с информацией о событиях, затем вторник в качестве заголовка, а затем 2 записи в таблице вторника.

Я понял, что мне может понадобиться группировка на основе дня недели. У меня мало опыта работы с xslt. Как мы go об этом? Браузеры не поддерживают 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>

1 Ответ

1 голос
/ 04 августа 2020

Давайте сосредоточимся на таблице стилей 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>
...