[英]Is it possible to transform a parsimonious XML to a full HTML table using XSLT 2.0?
非常重要的說明:我正在使用QtXmlPattern(未完全實現的XSLT 2.0處理器,在實現的內容中存在一些錯誤...)
我有一個格式良好的XML文件,其數據在四級數組中定義,如下所示:
<a>
<b>
<c day="20150221">
<d>...</d>
<e>...</e>
</c>
<c day="20150222">
<d>...</d>
<e>...</e>
</c>
<c day="20150223">
<d>...</d>
<e>...</e>
</c>
</b>
<b>
<c day="20150219">
<d>...</d>
<e>...</e>
</c>
<c day="20150221">
<d>...</d>
<e>...</e>
</c>
<c day="20150223">
<d>...</d>
<e>...</e>
</c>
</b>
...
</a>
結果應包括所有天數,但正如我們看到的那樣,每個<b>
列表可能都有不同的天數集。 但是結果需要所有<b>
標簽全天候運行。 如果沒有數據,則結果可能為空或為零。
我找到了一種收集變量中所有天數的方法:
<xsl:variable name="days" select="distinct-values(/a/b/c/@day)"/>
但是我看不到如何生成最終結果,就像下面這樣:
<table>
<th>
<td>20150219</td>
<td>20150221</td>
<td>20150222</td>
<td>20150223</td>
</th>
<tr>
<td>data from <d> tag on 20150219</td>
<td>data from <d> tag on 20150221</td>
<td>data from <d> tag on 20150222</td>
<td>data from <d> tag on 20150223</td>
</tr>
...[repeat for various data and calculation on the data]...
</table>
我的問題是變量不是節點列表,而是字符串列表,我不太確定如何遍歷字符串列表。
以防萬一,對於那些不了解QXmlQuery解析器的人, xsl:for-each-group
命令不存在。
您可以(使用XSLT 2.0,不確定所選擇的處理器是否支持該功能)就可以了
<xsl:variable name="main-doc" select="/">
將主文檔節點存儲在稍后將要定義的變量中,然后定義一個鍵
<xsl:key name="by-date" match="a/b/c/d" use="../@day"/>
然后在一天中引用d
項目
<xsl:for-each select="$days">
<xsl:variable name="d-on-day" select="key('by-date', ., $main-doc)"/>
帶有三個參數的那個key()
調用是XSLT 2.0中的新功能,如果不支持,請嘗試
<xsl:for-each select="$days">
<xsl:variable name="day" select="."/>
<xsl:for-each select="$main-doc">
<xsl:variable name="d-on-day" select="key('by-date', $day)"/>
...
</xsl:for-each>
...
</xsl:for-each>
如果key
功能不可用,則需要編寫引用,例如
<xsl:variable name="d-elements" select="/a/b/c/d"/>
<xsl:for-each select="$days">
<xsl:variable name="day" select="."/>
<xsl:for-each select="$d-elements[../@day = $day]">...</xsl:for-each>
</xsl:for-each>
我不確定您需要什么,但有時對嘗試的解決方案發表評論要比嘗試解釋容易。 您絕對必須使用鍵來查找不同的屬性值。
不要遍歷字符串列表,而是遍歷一系列c
元素,這些元素相對於其day
屬性的值是唯一的(最后是相同的)。 我在下面使用的技術由Jeni Tennison進行了描述,因為它通常用於分組問題。
XML輸入
我認為,明智的輸入包括d
元素的實際值:
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b>
<c day="20150221">
<d>data from day 20150221</d>
<e>...</e>
</c>
<c day="20150222">
<d>data from day 20150222</d>
<e>...</e>
</c>
<c day="20150223">
<d>data from day 20150223</d>
<e>...</e>
</c>
</b>
<b>
<c day="20150219">
<d>data from day 20150219</d>
<e>...</e>
</c>
<c day="20150221">
<d>data from day 20150221</d>
<e>...</e>
</c>
<c day="20150223">
<d>data from day 20150223</d>
<e>...</e>
</c>
</b>
<!--...-->
</a>
樣式表
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:key name="day-from-c" match="c" use="@day" />
<xsl:template match="/">
<hmtl>
<xsl:apply-templates/>
</hmtl>
</xsl:template>
<xsl:template match="a">
<table>
<xsl:variable name="days" select="b/c[generate-id() =
generate-id(key('day-from-c', @day)[1])]"/>
<xsl:for-each select="$days">
<xsl:sort select="@day"/>
<th>
<xsl:value-of select="@day"/>
</th>
</xsl:for-each>
<tr>
<xsl:for-each select="$days">
<xsl:sort select="@day"/>
<td>
<xsl:value-of select="/a/b/c[@day = current()/@day]/d"/>
</td>
</xsl:for-each>
</tr>
</table>
</xsl:template>
</xsl:transform>
HTML輸出
我仍然不清楚如果同一天有多個d
元素會發生什么。
<!DOCTYPE html
PUBLIC "XSLT-compat">
<hmtl>
<table>
<th>20150219</th>
<th>20150221</th>
<th>20150222</th>
<th>20150223</th>
<tr>
<td>data from day 20150219</td>
<td>data from day 20150221 data from day 20150221</td>
<td>data from day 20150222</td>
<td>data from day 20150223 data from day 20150223</td>
</tr>
</table>
</hmtl>
在xsltransform上在線嘗試此解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.