我有一个问题: - )
我想打印出一个xml并为它写一个xslt。问题是我想用我的xml元素构建一个表,但我必须计算每行是否有相同数量的列,如果不是我必须添加一个值元素。
我知道一旦我设置了值,我就无法更改变量值但是如何比较进程的分类/表行数呢? (并添加空行)
XML:
<Settings>
...
..
<DashBoard>
<Category NAME="ph" PICNAME="prh">
<Process NAME="pd" URL="" PICNAME="prh_prd" />
<Process NAME="md" URL="" PICNAME="prh_prd" />
<Process NAME="t" URL="" PICNAME="prh_prd" />
</Category>
<Category NAME="cm" PICNAME="cam">
<Process NAME="ps" URL="" PICNAME="cam_pls" />
<Process NAME="ea" URL="" PICNAME="cam_eas" />
</Category>
<Category NAME="sm" PICNAME="sum">
<Process NAME="frm" URL="" PICNAME="sum_frm" />
</Category>
</DashBoard>
</Settings>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl=".....">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="relurl" select="/Settings/Picture/@RELATIVEURL"/>
<xsl:template match="Settings">
<table id="dashframe" >
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="Category">
<xsl:variable name="altname" select="@NAME" />
<xsl:variable name="picname" select="@PICNAME" />
<tr>
<th>
<img alt="{$altname}" src="{$relurl}dash_{$picname}_p_01.png" />
</th>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="Process">
<xsl:variable name="altname" select="@NAME" />
<xsl:variable name="picname" select="@PICNAME" />
<td>
<img alt="{$altname}" src="{$relurl}dash_{$picname}_p_01.png" />
</td>
</xsl:template>
</xsl:stylesheet>
期望的输出:
<table id="dashframe" >
<tr>
<th>titel 1</th>
<td>....</td>
<td>....</td>
<td>....</td>
</tr>
<tr>
<th>titel 2</th>
<td>....</td>
<td>....</td>
<td></td>
</tr>
<tr>
<th>titel 3</th>
<td>....</td>
<td></td>
<td></td>
</tr>
</table>
答案 0 :(得分:1)
保留你的,这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="relurl" select="/Settings/Picture/@RELATIVEURL"/>
<xsl:variable name="vColumns">
<xsl:for-each select="/Settings/DashBoard/Category">
<xsl:sort select="count(Process)" order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="count(Process)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="DashBoard">
<table id="dashframe" border="1">
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="Category">
<tr>
<th>
<img alt="{@NAME}" src="{$relurl}dash_{@PICNAME}_p_01.png"/>
</th>
<xsl:call-template name="process"/>
</tr>
</xsl:template>
<xsl:template name="process">
<xsl:param name="pColumn" select="number($vColumns)"/>
<xsl:if test="$pColumn">
<xsl:call-template name="process">
<xsl:with-param name="pColumn" select="$pColumn - 1"/>
</xsl:call-template>
<td>
<xsl:variable name="vColumn" select="Process[$pColumn]"/>
<xsl:if test="$vColumn">
<img alt="{$vColumn/@NAME}"
src="{$relurl}dash_{$vColumn/@PICNAME}_p_01.png"/>
</xsl:if>
</td>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
使用此输入:
<Settings>
<DashBoard>
<Category NAME="ph" PICNAME="prh">
<Process NAME="pd" URL="" PICNAME="prh_prd" />
<Process NAME="md" URL="" PICNAME="prh_prd" />
<Process NAME="t" URL="" PICNAME="prh_prd" />
</Category>
<Category NAME="cm" PICNAME="cam">
<Process NAME="ps" URL="" PICNAME="cam_pls" />
<Process NAME="ea" URL="" PICNAME="cam_eas" />
</Category>
<Category NAME="sm" PICNAME="sum">
<Process NAME="frm" URL="" PICNAME="sum_frm" />
</Category>
</DashBoard>
</Settings>
输出:
<table id="dashframe" border="1">
<tr>
<th><img alt="ph" src="dash_prh_p_01.png"></th>
<td><img alt="pd" src="dash_prh_prd_p_01.png"></td>
<td><img alt="md" src="dash_prh_prd_p_01.png"></td>
<td><img alt="t" src="dash_prh_prd_p_01.png"></td>
</tr>
<tr>
<th><img alt="cm" src="dash_cam_p_01.png"></th>
<td><img alt="ps" src="dash_cam_pls_p_01.png"></td>
<td><img alt="ea" src="dash_cam_eas_p_01.png"></td>
<td></td>
</tr>
<tr>
<th><img alt="sm" src="dash_sum_p_01.png"></th>
<td><img alt="frm" src="dash_sum_frm_p_01.png"></td>
<td></td>
<td></td>
</tr>
</table>
注意:众所周知的最大成语。
答案 1 :(得分:1)
感谢您的回答,我在过去4-5小时内自己解决了~~~
首先,得到计数:
<xsl:variable name="maxProcess">
<xsl:call-template name="db"/>
</xsl:variable>
<xsl:template name="db">
<xsl:for-each select="/Settings/DashBoard/Category">
<xsl:sort select="count(Process)" order="descending"/>
<xsl:if test="position() =1">
<xsl:value-of select="count(Process)"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
第二步,添加进程,然后添加空的进程:
<xsl:template match="Category">
<tr>
<td>
<img .... />
</td>
<xsl:apply-templates/>
<xsl:call-template name="addTDs">
<xsl:with-param name="rest" select="$maxProcess - count(Process)"/>
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template match="Process">
<td>
<img ... />
</td>
</xsl:template>
<xsl:template name="addTDs">
<xsl:param name="rest"/>
<xsl:choose>
<xsl:when test="$rest > 0">
<td>
<img ..../>
</td>
<xsl:call-template name="addTDs">
<xsl:with-param name="rest" select="$rest - 1"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
答案 2 :(得分:0)
所以你应该分两步完成:
所以第一部分是这里的核心问题,因为不可能仅通过xpath找到它。
这个问题的答案证实:
Find the maximum child count with XPath 1.0
我现在试着回答这个问题约30分钟。由于我的工作,我对XML和XSLT非常熟悉。但我不能弄清楚如何找到具有最大子元素数的元素。但其他人之前做过:
Find maximum value of all child elements and get its parent element in XSLT
顺便说一句:这家伙在他的回答中失去了一个支持!如果你有,我们来到第2步:
在您的类别模板中,只需添加对以下模板的调用(这只是for循环):
<xsl:template name="for.loop">
<xsl:param name="i" />
<xsl:param name="count" />
<xsl:if test="$i <= $count">
//Generate your "fill up" - colum here
</xsl:if>
<!--begin_: RepeatTheLoopUntilFinished-->
<xsl:if test="$i <= $count">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
现在你调用该模板简单填写count(Process)
作为参数,并将计数填入先前保存的“最大” - 您从链接问题{{1}中的第一个模板获得的节点作为参数计数。
叹息似乎是你遇到了一些XSLT很难的点。
希望有所帮助!