2016-05-22 2 views
0

У меня есть отчет XML с почасовыми значениями в строке. Я хотел бы перераспределить эти значения таким образом: - одна колонка в час - одна строка в деньКак перераспределить часы в ежемесячном отчете в таблицу с XSLT

Что послужило бы основой для XSL, который бы перераспределял эти значения? Вот snipet из файла XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Report > 
    <Heading> 
     <General_information> 
      <Date Execution="2016-05-20 22:15:00+02:00" Begin="2012-04-01 00:00:00+02:00" End="2012-05-01 00:00:00+02:00" TimeOffset="+02:00" DST="-1"/> 
      <Calculation_description>Monthly-hourly report</Calculation_description> 
     </General_information> 
    </Heading> 
    <Results_list Repetition="3600" > 
     <Label>Hour</Label> 
     <Result_line Number="2" Epoch="1333234800" Date="2012-04-01 01:00:00+02:00"> 
      <Line_name>2012-04-01 01:00:00+02:00</Line_name> 
      <Val> </Val> 
     </Result_line> 
    ... 
     <Result_line Number="476" Epoch="1334941200" Date="2012-04-20 19:00:00+02:00"> 
      <Line_name>2012-04-20 19:00:00+02:00</Line_name> 
      <Val >13.16</Val> 
     </Result_line> 
     <Result_line Number="477" Epoch="1334944800" Date="2012-04-20 20:00:00+02:00"> 
      <Line_name>2012-04-20 20:00:00+02:00</Line_name> 
      <Val >15.93</Val> 
     </Result_line> 
    ... 
     <Result_line Number="720" Epoch="1335819600" Date="2012-04-30 23:00:00+02:00"> 
      <Line_name>2012-04-30 23:00:00+02:00</Line_name> 
      <Val>25.52</Val> 
     </Result_line> 
     <Result_line Number="721" Epoch="1335823200" Date="2012-05-01 00:00:00+02:00"> 
      <Line_name>2012-05-01 00:00:00+02:00</Line_name> 
      <Val >38.52</Val> 
     </Result_line> 
    </Results_list> 
</Report> 

Я думал о базировании решения либо по атрибуту Result_line/@Number модуль 24 или Result_line/@Date атрибутов подстроки в. Но я занимаюсь только for-each циклами, которые, как я подозреваю, являются плохим решением.

Вне курса Я бы добавил колонки заголовка и даты на более позднем этапе.

На данный момент я знаю, что использую XSLT 1.0.

Благодаря

+0

Всегда ли будет один «Result_line» для каждого часа в заданном диапазоне? И будет ли каждый день 24 часа? По-видимому, нет, так как ваш пример начинается с Number = 2. –

+0

one Result_line для каждого часа: да, номер начинается с 2 всегда (не знаю почему). – Alex

+0

Всегда 24 часа в сутки, давайте считать, что это правда (это может быть от 23 до 25 часов при переключении зимнего/летнего времени, но я обойдусь). – Alex

ответ

1

Если ваша таблица регулярно, и каждая дата начинается час = 2 и имеет ровно 24 часа, перечисленные в порядке, вы могли бы сделать что-то очень простое, как:

XSLT 1.0

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

<xsl:template match="/Report"> 
    <table border="1"> 
     <thead> 
      <tr> 
       <th/> 
       <xsl:for-each select="Results_list/Result_line[position() &lt; 24]"> 
        <th> 
         <xsl:value-of select="@Number"/> 
        </th> 
       </xsl:for-each> 
      </tr> 
     </thead> 
     <tbody> 
      <xsl:for-each select="Results_list/Result_line[@Number mod 24 = 2]"> 
       <tr> 
        <th> 
         <xsl:value-of select="substring-before(@Date, ' ')"/> 
        </th> 
        <xsl:for-each select=". | following-sibling::Result_line[position() &lt; 23]"> 
         <td> 
          <xsl:value-of select="Val"/> 
         </td> 
        </xsl:for-each> 
       </tr> 
      </xsl:for-each> 
     </tbody> 
    </table> 
</xsl:template> 

</xsl:stylesheet> 

Однако это будет неудачей, если дата разрешено иметь 23 или 25 часов.


В качестве альтернативы, вы можете сгруппировать строки по дате, используя Muenchian grouping, и создать ячейку для каждой строки в строке в Дейта:

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

<xsl:key name="line-by-date" match="Result_line" use="substring-before(@Date, ' ')" /> 

<xsl:template match="/Report"> 
    <table border="1"> 
     <xsl:for-each select="Results_list/Result_line[count(. | key('line-by-date', substring-before(@Date, ' '))[1]) = 1]"> 
      <xsl:variable name="date" select="substring-before(@Date, ' ')" /> 
       <tr> 
        <th> 
         <xsl:value-of select="$date"/> 
        </th>     
        <xsl:for-each select="key('line-by-date', $date)"> 
         <td> 
          <xsl:value-of select="Val"/> 
         </td> 
        </xsl:for-each> 
       </tr> 
     </xsl:for-each> 
    </table> 
</xsl:template> 

</xsl:stylesheet> 

Я не включать заголовок таблицы здесь, потому что я не знаю, что он должен показать.

+0

Спасибо большое Майкл! Я мог бы управлять на основе обоих решений. Alexandre – Alex