2016-02-23 4 views
0

У меня есть файл XML о погодных данных из 3 разных городов, теперь я хочу использовать XSl для преобразования его в 3 таблицы в соответствии с атрибутами местоположения (Calgary, Charlottetown и Ottawa) в моем xml. Теперь у меня есть xls, который превращает xml в одну таблицу. Может ли кто-нибудь дать мне подсказку о том, как преобразовать xml-файл в разные таблицы с помощью атрибута xml?
Это мой XMLXSL Преобразование XML-файла в 3 таблицы

<?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> 
+0

имена местоположение - Калгари, Шарлоттетаун и Оттава - известно заранее? IOW, могут ли они быть жестко закодированы в таблицу стилей? –

ответ

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> 
+0

Большое спасибо, он отлично фильтрует данные в 3 разных городах, но все данные не организованы в таблицах, я пытался добавить теги

, он не работает. @ michael.hor257k –

+0

"* все данные не организованы в таблицах *« Я не уверен, что вы подразумеваете под этим. Результатом является три таблицы, каждая из которых содержит три строки данных. В вашем XML есть 9 элементов 'stationdata', и что именно не хватает? –

+0

Теперь он работает, я только что заменил выходной метод = "xml" в прологе метода output = "html". @ michael.hor257k –

1

Это групповой вопрос. Поскольку вы используете XSLT 1.0, вы можете использовать Muenchian Grouping.

Вы можете создать xsl:key на основе атрибута location.

Затем вы перебираете первое соответствие каждой клавиши и выводите местоположение.

Затем вы применяете шаблоны ко всем совпадениям с этим ключом.

XML Input

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

<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> 
+0

Большое спасибо, эта работа отлично. Я новичок в XSL, это будет намного проще на XSL 2.0? @Daniel Haley –

+0

@Z.Zhe - Для этого небольшого примера, это не намного проще в 2.0. Однако, если ваша группировка усложняется или существуют другие области, которые необходимо преобразовать дальше (например, даты форматирования и т. Д.), В 2.0 это будет намного проще. Я обновляю свой ответ с помощью примера 2.0. Кроме того, если этого ответа достаточно, примите его, нажав галочку (✅) рядом с ней. Благодаря! –

+0

Спасибо, @ Дэниел Хейли, я попытаюсь изучить ссылку, которую вы предоставляете. очень ценю –

Смежные вопросы