![](/img/trans.png)
[英]How to create html table from XML element attributes and XML tags using xslt
[英]Trying to use XSLT to create HTML table from XML
我在XSLT方面苦苦掙扎。 我被困在程序上。 基本上,我有一些從數據庫生成的XML,看起來像這樣:
<?xml version="1.0" encoding="iso-8859-1"?>
<report>
<generated_dtm>2013-03-08T18:57:26+00:00</generated_dtm>
<range>
<start_dtm>2013-02-21T17:52:00+00:00</start_dtm>
<end_dtm>2013-03-08T17:52:00+00:00</end_dtm>
</range>
<sensor site_code="A0001" unit_no="1" sensor_no="1">
<name>Food</name>
<mu_symbol>°C</mu_symbol>
</sensor>
<sensor site_code="A0001" unit_no="1" sensor_no="2">
<name>Air</name>
<mu_symbol>°C</mu_symbol>
</sensor>
<readings>
<slot slot_dtm="2013-02-21T17:50:00+00:00">
<sensor sensor_no="1">
<v>10</v>
<status_code>IR</status_code>
<status_desc>In Range</status_desc>
</sensor>
<sensor sensor_no="2">
<v>20</v>
<status_code>Lo</status_code>
<status_desc>Low</status_desc>
</sensor>
</slot>
<slot slot_dtm="2013-02-21T18:00:00+00:00">
<sensor sensor_no="2">
<v>21</v>
<status_code>Lo</status_code>
<status_desc>Low</status_desc>
</sensor>
<sensor sensor_no="1">
<v>11</v>
<status_code>IR</status_code>
<status_desc>In Range</status_desc>
</sensor>
</slot>
</readings>
</report>
我試圖以HTML表中的讀數結束,每個傳感器都是一列,每一行的時間都在左側,如下所示:
Time | Food | Air
-------------------------------------
2013-02-21T17:50:00+00:00 | 10 | 11
2013-02-21T18:00:00+00:00 | 20 | 22
盡管可以保證時隙的順序是遞增的,所以我不需要對其進行排序(可以是1000),但問題是在每個時隙內不能保證傳感器的順序,所以我認為我將遍歷用於創建表標題的傳感器,並在每次迭代插槽時從每個插槽中選擇正確的傳感器。 盡管這不起作用,您可能會得到我嘗試做的事情(我現在知道為什么它不起作用了。變量不符合我的預期!):-
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="report">
<html>
<head>
<title>Report</title>
</head>
<body>
<table border="0" width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="2">
<tr>
<td class="column_head_above" width="70">Time</td>
<xsl:for-each select="sensor">
<td class="column_head_above"><xsl:value-of select="name"/><xsl:text> </xsl:text><xsl:value-of select="mu_symbol"/></td>
</xsl:for-each>
</tr>
<!-- go through each time slot -->
<xsl:for-each select="readings/slot">
<tr>
<xsl:variable name="sdtm" select="@slot_dtm" />
<td class="table_data"><xsl:value-of select="$sdtm"/></td>
<!-- go through each sensor header -->
<xsl:for-each select="../sensor">
<xsl:variable name="sno" select="@sensor_no" />
<td>
<xsl:value-of select="../readings/slot[@slot_dtm=$sdtm]/sensor[@sensor_no=$sno]/v"/>
<xsl:value-of select="../readings/slot[@slot_dtm=$sdtm]/sensor[@sensor_no=$sno]/status_desc"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
<!-- end: go through each time slot -->
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
可以有100甚至1000個時隙,這只是一個小例子。 如果有幫助,我可以調整XML的層次結構,但是如果不認真修改數據庫查詢,就無法在每個時隙內按順序排列傳感器。 我希望那不是必需的。
最初,我使用XML來分隔插槽,如下所示:
<readings>
<slot slot_dtm="2013-02-21T17:50:00+00:00">
<sensor sensor_no="1">
<v>10</v>
<status_code>IR</status_code>
<status_desc>In Range</status_desc>
</sensor>
</slot>
<slot slot_dtm="2013-02-21T17:50:00+00:00">
<sensor sensor_no="2">
<v>20</v>
<status_code>Lo</status_code>
<status_desc>Low</status_desc>
</sensor>
</slot>
<slot slot_dtm="2013-02-21T18:00:00+00:00">
<sensor sensor_no="1">
<v>11</v>
<status_code>IR</status_code>
<status_desc>In Range</status_desc>
</sensor>
</slot>
<slot slot_dtm="2013-02-21T18:00:00+00:00">
<sensor sensor_no="2">
<v>21</v>
<status_code>Lo</status_code>
<status_desc>Low</status_desc>
</sensor>
</slot>
</readings>
其中涉及一個簡單得多的數據庫查詢! 在這里,我可以保證順序,但是我使用的XQuery處理器(Qt的QXmlQuery)不支持for-each-group,因此我找不到基於時間進行分組的方法。
很抱歉,這個時間太長了,我希望有人能至少幫助我指出正確的方向。
謝謝。
應該這樣做:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="allSensors" select="/report/sensor" />
<xsl:template match="report">
<html>
<head>
<title>Report</title>
</head>
<body>
<table border="0" width="100%" bgcolor="#ffffff"
cellspacing="0" cellpadding="2">
<tr>
<td class="column_head_above" width="70">Time</td>
<xsl:apply-templates select="sensor" />
</tr>
<xsl:apply-templates select="readings/slot" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="report/sensor">
<td class="column_head_above">
<xsl:value-of select="concat(name, ' ', mu_symbol)"/>
</td>
</xsl:template>
<xsl:template match="slot">
<xsl:variable name="currentSensors" select="sensor" />
<tr>
<td class="table_data">
<xsl:value-of select="@slot_dtm"/>
</td>
<xsl:apply-templates select="$allSensors/@sensor_no">
<xsl:with-param name="currentSlot" select="current()/@slot_dtm" />
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="@sensor_no">
<xsl:param name="currentSlot" />
<td>
<xsl:variable name="matchingSensor"
select="/report/readings/slot[@slot_dtm = $currentSlot]
/sensor[@sensor_no = current()]" />
<xsl:value-of select="concat($matchingSensor/v, ' - ',
$matchingSensor/status_desc)" />
</td>
</xsl:template>
</xsl:stylesheet>
我在這里做了一些清理,但是要點是:
for-each
內部引用。 在樣本輸入上運行時,將產生:
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Report</title>
</head>
<body>
<table border="0" width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="2">
<tr>
<td class="column_head_above" width="70">Time</td>
<td class="column_head_above">Food °C</td>
<td class="column_head_above">Air °C</td>
</tr>
<tr>
<td class="table_data">2013-02-21T17:50:00+00:00</td>
<td>10 - In Range</td>
<td>20 - Low</td>
</tr>
<tr>
<td class="table_data">2013-02-21T18:00:00+00:00</td>
<td>11 - In Range</td>
<td>21 - Low</td>
</tr>
</table>
</body>
</html>
這是花了一些時間弄清楚后的更新。 也感謝JLRishe的回答。 在那和我已經解決的問題之間,事情開始變得清晰起來(直到下一個問題!)。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="report">
<html>
<head>
<title>Report</title>
</head>
<body>
<table border="0" width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="2">
<tr>
<td class="column_head_above" width="70">Time</td>
<xsl:apply-templates select="sensors/sensor">
<xsl:sort select="@sensor_no" />
</xsl:apply-templates>
</tr>
<!-- go through each time slot -->
<xsl:for-each select="readings/slot">
<tr>
<td class="table_data"><xsl:value-of select="@slot_dtm"/></td>
<!-- go through each sensor header -->
<xsl:apply-templates select="sensor">
<xsl:sort select="@sensor_no" />
</xsl:apply-templates>
</tr>
</xsl:for-each>
<!-- end: go through each time slot -->
</table>
</body>
</html>
</xsl:template>
<xsl:template match="slot/sensor">
<td>
<xsl:value-of select="@sensor_no"/> -
<xsl:value-of select="v"/> -
<xsl:value-of select="status_desc"/>
</td>
</xsl:template>
<xsl:template match="sensors/sensor">
<td class="column_head_above">
<xsl:value-of select="name"/><xsl:text> </xsl:text><xsl:value-of select="mu_symbol"/>
</td>
</xsl:template>
</xsl:stylesheet>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.