XSL将XML文件转换为3个表

时间:2016-02-23 17:56:01

标签: xml xslt

我有一个关于3个不同城市的天气数据的XML文件,现在我想使用XSl根据我的xml中的位置(卡尔加里,夏洛特敦和渥太华)将其转换为3个表。我现在的xls只是将xml转换成一个表,任何人都可以给我一个关于如何通过xml属性将xml文件转换为不同表的提示吗? 这是我的xml

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="weatherdata.xsl"?>
<weatherdata>
<stationdata weatherdate="2015-1-1" location="Calgary">
<maxtemp>1.1°C</maxtemp>
<mintemp>-6.1°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-1-2" location="Calgary">
<maxtemp>-3.4°C</maxtemp>
<mintemp>-18.2°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>5cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-1-3" location="Calgary">
<maxtemp>-18.1°C</maxtemp>
<mintemp>-21.1°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>1.6cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-01-01" location="Charlottetown">
<maxtemp>-3.5°C</maxtemp>
<mintemp>-15°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0.4cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-01-02" location="Charlottetown">
<maxtemp>-1°C</maxtemp>
<mintemp>-13.2°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0.6cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-01-03" location="Charlottetown">
<maxtemp>-11.8°C</maxtemp>
<mintemp>-16.1°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0cm</totalsnow>
</stationdata>
stationdata weatherdate="2015-01-01" location="Ottawa">
<maxtemp>-3°C</maxtemp>
<mintemp>-8.1°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0.2cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-01-02" location="Ottawa">
<maxtemp>-3.8°C</maxtemp>
<mintemp>-15.8°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>0cm</totalsnow>
</stationdata>
<stationdata weatherdate="2015-01-03" location="Ottawa">
<maxtemp>-9.6°C</maxtemp>
<mintemp>-15.5°C</mintemp>
<totalrain>0 mm</totalrain>
<totalsnow>18cm</totalsnow>
</stationdata>
</weatherdata>

这是我的xls

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/weatherdata">
<html>
 <head>
 <title>weather data</title>
 </head>
 <body>

<h1>Calgary-Temperature Summary(2015)</h1>
<table border="1">
    <tr>
        <th>Data</th>
        <th>Maximum Temperature(°C)</th>
        <th>Minimum Temperature(°C)</th>
        <th>Total Rain(mm)</th>
        <th>Total Snow(cm)</th>
    </tr>
 <xsl:apply-templates/>
 </table>
 </body>
</html>
 </xsl:template>

 <xsl:template match="stationdata">
<tr>
                <td><xsl:value-of select="@weatherdate"/></td>
                <td><xsl:value-of select="maxtemp"/></td>
                <td><xsl:value-of select="mintemp"/></td>
                <td><xsl:value-of select="totalrain"/></td>
                <td><xsl:value-of select="totalsnow"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

假设位置名称 - 卡尔加里,夏洛特敦和渥太华 - 提前知道并且始终存在,您可以这样做:

XSLT 1.0

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

<xsl:variable name="thead">
    <tr>
        <th>Data</th>
        <th>Maximum Temperature(°C)</th>
        <th>Minimum Temperature(°C)</th>
        <th>Total Rain(mm)</th>
        <th>Total Snow(cm)</th>
    </tr>
</xsl:variable>

<xsl:template match="/weatherdata">
    <html>
        <head>
            <title>weather data</title>
        </head>
        <body>
            <h1>Calgary-Temperature Summary(2015)</h1>
            <table border="1">
                <xsl:copy-of select="$thead"/>
                <xsl:apply-templates select="stationdata[@location='Calgary']"/>
            </table>
            <h1>Charlottetown-Temperature Summary(2015)</h1>
            <table border="1">
                <xsl:copy-of select="$thead"/>
                <xsl:apply-templates select="stationdata[@location='Charlottetown']"/>
            </table>
            <h1>Ottawa-Temperature Summary(2015)</h1>
            <table border="1">
                <xsl:copy-of select="$thead"/>
                <xsl:apply-templates select="stationdata[@location='Ottawa']"/>
            </table>
        </body>
    </html>
</xsl:template>

<xsl:template match="stationdata">
    <tr>
        <td><xsl:value-of select="@weatherdate"/></td>
        <td><xsl:value-of select="maxtemp"/></td>
        <td><xsl:value-of select="mintemp"/></td>
        <td><xsl:value-of select="totalrain"/></td>
        <td><xsl:value-of select="totalsnow"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

这是一个分组问题。由于您使用的是XSLT 1.0,因此可以使用Muenchian Grouping

您可以根据xsl:key属性创建location

然后循环遍历每个键的第一个匹配并输出位置。

然后将模板应用于与该键匹配的所有匹配项。

XML输入

<weatherdata>
    <stationdata weatherdate="2015-1-1" location="Calgary">
        <maxtemp>1.1°C</maxtemp>
        <mintemp>-6.1°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-1-2" location="Calgary">
        <maxtemp>-3.4°C</maxtemp>
        <mintemp>-18.2°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>5cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-1-3" location="Calgary">
        <maxtemp>-18.1°C</maxtemp>
        <mintemp>-21.1°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>1.6cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-01" location="Charlottetown">
        <maxtemp>-3.5°C</maxtemp>
        <mintemp>-15°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0.4cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-02" location="Charlottetown">
        <maxtemp>-1°C</maxtemp>
        <mintemp>-13.2°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0.6cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-03" location="Charlottetown">
        <maxtemp>-11.8°C</maxtemp>
        <mintemp>-16.1°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-01" location="Ottawa">
        <maxtemp>-3°C</maxtemp>
        <mintemp>-8.1°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0.2cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-02" location="Ottawa">
        <maxtemp>-3.8°C</maxtemp>
        <mintemp>-15.8°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>0cm</totalsnow>
    </stationdata>
    <stationdata weatherdate="2015-01-03" location="Ottawa">
        <maxtemp>-9.6°C</maxtemp>
        <mintemp>-15.5°C</mintemp>
        <totalrain>0 mm</totalrain>
        <totalsnow>18cm</totalsnow>
    </stationdata>
</weatherdata>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="locations" match="stationdata" use="@location"/>

  <xsl:template match="/weatherdata">
    <html>
      <head>
        <title>weather data</title>
      </head>
      <body>
        <xsl:for-each select="stationdata[count(.|key('locations',@location)[1])=1]">
          <h1><xsl:value-of select="@location"/>-Temperature Summary (<xsl:value-of select="substring-before(@weatherdate,'-')"/>)</h1>
          <table border="1">
            <tr>
              <th>Data</th>
              <th>Maximum Temperature(°C)</th>
              <th>Minimum Temperature(°C)</th>
              <th>Total Rain(mm)</th>
              <th>Total Snow(cm)</th>
            </tr>
            <xsl:apply-templates select="key('locations',@location)"/>
          </table>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="stationdata">
    <tr>
      <td><xsl:value-of select="@weatherdate"/></td>
      <td><xsl:value-of select="maxtemp"/></td>
      <td><xsl:value-of select="mintemp"/></td>
      <td><xsl:value-of select="totalrain"/></td>
      <td><xsl:value-of select="totalsnow"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

HTML输出

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
      <title>weather data</title>
   </head>
   <body>
      <h1>Calgary-Temperature Summary (2015)</h1>
      <table border="1">
         <tr>
            <th>Data</th>
            <th>Maximum Temperature(&deg;C)</th>
            <th>Minimum Temperature(&deg;C)</th>
            <th>Total Rain(mm)</th>
            <th>Total Snow(cm)</th>
         </tr>
         <tr>
            <td>2015-1-1</td>
            <td>1.1&deg;C</td>
            <td>-6.1&deg;C</td>
            <td>0 mm</td>
            <td>0cm</td>
         </tr>
         <tr>
            <td>2015-1-2</td>
            <td>-3.4&deg;C</td>
            <td>-18.2&deg;C</td>
            <td>0 mm</td>
            <td>5cm</td>
         </tr>
         <tr>
            <td>2015-1-3</td>
            <td>-18.1&deg;C</td>
            <td>-21.1&deg;C</td>
            <td>0 mm</td>
            <td>1.6cm</td>
         </tr>
      </table>
      <h1>Charlottetown-Temperature Summary (2015)</h1>
      <table border="1">
         <tr>
            <th>Data</th>
            <th>Maximum Temperature(&deg;C)</th>
            <th>Minimum Temperature(&deg;C)</th>
            <th>Total Rain(mm)</th>
            <th>Total Snow(cm)</th>
         </tr>
         <tr>
            <td>2015-01-01</td>
            <td>-3.5&deg;C</td>
            <td>-15&deg;C</td>
            <td>0 mm</td>
            <td>0.4cm</td>
         </tr>
         <tr>
            <td>2015-01-02</td>
            <td>-1&deg;C</td>
            <td>-13.2&deg;C</td>
            <td>0 mm</td>
            <td>0.6cm</td>
         </tr>
         <tr>
            <td>2015-01-03</td>
            <td>-11.8&deg;C</td>
            <td>-16.1&deg;C</td>
            <td>0 mm</td>
            <td>0cm</td>
         </tr>
      </table>
      <h1>Ottawa-Temperature Summary (2015)</h1>
      <table border="1">
         <tr>
            <th>Data</th>
            <th>Maximum Temperature(&deg;C)</th>
            <th>Minimum Temperature(&deg;C)</th>
            <th>Total Rain(mm)</th>
            <th>Total Snow(cm)</th>
         </tr>
         <tr>
            <td>2015-01-01</td>
            <td>-3&deg;C</td>
            <td>-8.1&deg;C</td>
            <td>0 mm</td>
            <td>0.2cm</td>
         </tr>
         <tr>
            <td>2015-01-02</td>
            <td>-3.8&deg;C</td>
            <td>-15.8&deg;C</td>
            <td>0 mm</td>
            <td>0cm</td>
         </tr>
         <tr>
            <td>2015-01-03</td>
            <td>-9.6&deg;C</td>
            <td>-15.5&deg;C</td>
            <td>0 mm</td>
            <td>18cm</td>
         </tr>
      </table>
   </body>
</html>

评论中提到的XSLT 2.0示例。如您所见,这个基本示例没有太大区别。我们只使用xsl:for-each-group而不是密钥。

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/weatherdata">
    <html>
      <head>
        <title>weather data</title>
      </head>
      <body>
        <xsl:for-each-group select="stationdata" group-by="@location">
          <h1><xsl:value-of select="current-grouping-key()"/>-Temperature Summary (<xsl:value-of select="substring-before(@weatherdate,'-')"/>)</h1>
          <table border="1">
            <tr>
              <th>Data</th>
              <th>Maximum Temperature(°C)</th>
              <th>Minimum Temperature(°C)</th>
              <th>Total Rain(mm)</th>
              <th>Total Snow(cm)</th>
            </tr>
            <xsl:apply-templates select="current-group()"/>
          </table>
        </xsl:for-each-group>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="stationdata">
    <tr>
      <td><xsl:value-of select="@weatherdate"/></td>
      <td><xsl:value-of select="maxtemp"/></td>
      <td><xsl:value-of select="mintemp"/></td>
      <td><xsl:value-of select="totalrain"/></td>
      <td><xsl:value-of select="totalsnow"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>