我正在使用xslt、创建动态表(网格)
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="RowAttribsByName" match="Row/@*"
use="concat(generate-id(..), '|', name())"/>
<xsl:variable name="vColNames" select=
"/*/Columns/*[not(@Hidden = 'true')]/@Name"/>
<xsl:template match="/*">
<table border="1">
<tr>
<xsl:apply-templates select="Columns/*"/>
</tr>
<xsl:apply-templates select="Rows/Row"/>
</table>
</xsl:template>
<xsl:template match="Column[not(@Hidden = 'true')]">
<td><xsl:value-of select="@Caption"/></td>
</xsl:template>
<xsl:template match="Row">
<tr>
<xsl:apply-templates select="$vColNames">
<xsl:with-param name="pRowId"
select="generate-id()"/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="Column/@*">
<xsl:param name="pRowId"/>
<td width="50%">
<xsl:value-of select=
"key('RowAttribsByName',
concat($pRowId, '|', .)
)
"/>
</td>
</xsl:template>
</xsl:stylesheet>
XML数据:
<TableData>
<Columns>
<Column Name="ID" Hidden="true" />
<Column Name="Name" Caption="Item Name" Link="Yes" Sort="Yes"/>
<Column Name="Desc" Caption="Item Description" />
</Columns>
<Rows>
<Row ID="0" Name="A" />
<Row ID="1" Name="B" Desc="Some description"/>
<Row ID="3" Name="C" />
</Rows>
</TableData>
预期输出:
<table border="1">
<tbody>
<tr>
<td>
<a onclick="javascript:SortColumn('Item Name')">Item Name</a>
</td>
<td>
<a onclick="javascript:SortColumn('Item Description')">Item Name</a></td>
</tr>
<tr>
<td width="50%">
<a onclick="javascript:OpenDifferentPage('A','0')">A</a>
</td>
<td width="50%"></td>
</tr>
<tr>
<td width="50%">B</td>
<td width="50%">Some description</td>
</tr>
<tr>
<td width="50%">C</td>
<td width="50%"></td>
</tr>
</tbody>
</table>
我是XSLT、的初学者
我想在这里检查一下,如果列有"链接"属性="是",那么我需要在锚标记(名称)之间显示数据。
我在本专栏中创建了许多复杂的功能。因此,我可以在这里为特定列制作模板(列是15,但这取决于用户的选择,如果用户选择8列进行显示,它还必须维护列的顺序)
最好是,如果我可以为所有列创建新模板,并根据传递的列数据维护列顺序。
感谢您的期待
对于XSLT初学者来说,您已经有了一个非常好的开始,尤其是使用xsl:key。
要回答您眼前的问题,您可以做些什么,而不是像现在这样让一个模板与Column元素的属性相匹配。。。。
<xsl:template match="Column/@*">
当Link属性设置为时,您可以有一个与之匹配的显式模板
<xsl:template match="Column[@Link='Yes']/@*">
在这个模板中,您可以添加额外的代码来输出链接。请注意,如果您将实际的Row作为参数传入,而不是将该行的generate id的值作为参数,则可能会稍微简单一些,因为这会使获取id属性的过程稍微不那么冗长。
<xsl:template match="Column[@Link='Yes']/@*">
<xsl:param name="pRow"/>
<xsl:variable name="pRowId" select="generate-id($pRow)"/>
<xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))" />
<td width="50%">
<a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
<xsl:value-of select="$pValue"/>
</a>
</td>
</xsl:template>
请注意,在创建onclick属性时,此处使用了"属性值模板"。大括号表示要计算的表达式,而不是实际输出。
为了使此模板工作,您还需要修改其他模板,以显式匹配Link属性未设置为"Yes"的属性
<xsl:template match="Column[not(@Link='Yes')]/@*">
这是因为,否则原始模板将与Link为"是"的情况相匹配,优先级与新模板相同,这是不允许的。
尝试此XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="RowAttribsByName" match="Row/@*" use="concat(generate-id(..), '|', name())"/>
<xsl:variable name="vColNames" select="/*/Columns/*[not(@Hidden = 'true')]/@Name"/>
<xsl:template match="/*">
<table border="1">
<tr>
<xsl:apply-templates select="Columns/*"/>
</tr>
<xsl:apply-templates select="Rows/Row"/>
</table>
</xsl:template>
<xsl:template match="Column[not(@Hidden = 'true')]">
<td>
<xsl:value-of select="@Caption"/>
</td>
</xsl:template>
<xsl:template match="Row">
<tr>
<xsl:apply-templates select="$vColNames">
<xsl:with-param name="pRow" select="."/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="Column[not(@Link='Yes')]/@*">
<xsl:param name="pRow"/>
<xsl:variable name="pRowId" select="generate-id($pRow)"/>
<xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
<td width="50%">
<xsl:value-of select="$pValue"/>
</td>
</xsl:template>
<xsl:template match="Column[@Link='Yes']/@*">
<xsl:param name="pRow"/>
<xsl:variable name="pRowId" select="generate-id($pRow)"/>
<xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
<td width="50%">
<a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
<xsl:value-of select="$pValue"/>
</a>
</td>
</xsl:template>
</xsl:stylesheet>
这种方法有几个缺点。有一些重复的代码,而且如果Column元素上有其他影响列输出的属性,管理起来也会更困难。
这里是XSLT的另一个版本,它使用模式元素来重复匹配Column属性,允许您在需要时潜在地输出更多元素
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="RowAttribsByName" match="Row/@*" use="concat(generate-id(..), '|', name())"/>
<xsl:variable name="vColNames" select="/*/Columns/*[not(@Hidden = 'true')]/@Name"/>
<xsl:template match="/*">
<table border="1">
<tr>
<xsl:apply-templates select="Columns/*"/>
</tr>
<xsl:apply-templates select="Rows/Row"/>
</table>
</xsl:template>
<xsl:template match="Column[not(@Hidden = 'true')]">
<td>
<xsl:value-of select="@Caption"/>
</td>
</xsl:template>
<xsl:template match="Row">
<tr>
<xsl:apply-templates select="$vColNames">
<xsl:with-param name="pRow" select="."/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="Column/@Name">
<xsl:param name="pRow"/>
<xsl:variable name="pRowId" select="generate-id($pRow)"/>
<xsl:variable name="pValue" select="key('RowAttribsByName', concat($pRowId, '|', .))"/>
<td width="50%">
<xsl:apply-templates select=".." mode="link">
<xsl:with-param name="pRow" select="$pRow"/>
<xsl:with-param name="pValue" select="$pValue"/>
</xsl:apply-templates>
</td>
</xsl:template>
<xsl:template match="Column[@Link='Yes']" mode="link">
<xsl:param name="pRow"/>
<xsl:param name="pValue"/>
<a onclick="javascript:OpenDifferentPage('{$pValue}','{$pRow/@ID}')">
<xsl:apply-templates select="self::*" mode="value">
<xsl:with-param name="pRow" select="$pRow"/>
<xsl:with-param name="pValue" select="$pValue"/>
</xsl:apply-templates>
</a>
</xsl:template>
<xsl:template match="Column" mode="link">
<xsl:param name="pRow"/>
<xsl:param name="pValue"/>
<xsl:apply-templates select="self::*" mode="value">
<xsl:with-param name="pRow" select="$pRow"/>
<xsl:with-param name="pValue" select="$pValue"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Column" mode="value">
<xsl:param name="pRow"/>
<xsl:param name="pValue"/>
<xsl:value-of select="$pValue"/>
</xsl:template>
</xsl:stylesheet>
注意,在本例中,链接有两个模板
<xsl:template match="Column[@Link='Yes']" mode="link">
<xsl:template match="Column" mode="link">
在这种情况下,第二个不需要检查Link属性。在模板只匹配显式元素名称的情况下,它的优先级将低于用xpath表达式限定的模板。因此,第二个模板将永远不会匹配Link为Yes的情况。
这个XSLT1.0样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="linked-cols" match="Column[@Link='Yes']" use="@Name" />
<xsl:template match="TableData">
<table border="1">
<tbody>
<xsl:variable name="cols" select="count(Columns/Column[not(@Hidden='true')])" />
<xsl:apply-templates>
<xsl:with-param name="col-width" select="concat(100 div $cols,'%')" />
</xsl:apply-templates>
</tbody>
</table>
</xsl:template>
<xsl:template match="Columns">
<tr>
<xsl:apply-templates />
</tr>
</xsl:template>
<xsl:template match="Column[@Hidden='true']" />
<xsl:template match="Column[@Sort='Yes']">
<td>
<a onclick="javascript:SortColumn('{@Caption}')"><xsl:value-of select="@Caption" /></a>
</td>
</xsl:template>
<xsl:template match="Column">
<td><xsl:value-of select="@Caption" /></td>
</xsl:template>
<xsl:template match="Rows">
<xsl:param name="col-width" />
<xsl:apply-templates>
<xsl:with-param name="col-width" select="$col-width" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Row">
<xsl:param name="col-width" />
<tr>
<xsl:variable name="Row" select="." />
<xsl:for-each select="../../Columns/Column[not(@Hidden='true')]">
<td width="{$col-width}">
<xsl:variable name="col-name" select="@Name" />
<xsl:apply-templates select="$Row/@*[local-name() = $col-name]" />
</td>
</xsl:for-each>
</tr>
</xsl:template>
<xsl:template match="Row/@*">
<xsl:value-of select="." />
</xsl:template>
<xsl:template match="Row/@*[key('linked-cols',local-name())]">
<a onclick="javascript:OpenDifferentPage('{.}','{../@ID}')"><xsl:value-of select="." /></a>
</xsl:template>
</xsl:stylesheet>
。。。应用于此文档时
<TableData>
<Columns>
<Column Name="ID" Hidden="true" />
<Column Name="Name" Caption="Item Name" Link="Yes" Sort="Yes"/>
<Column Name="Desc" Caption="Item Description" />
</Columns>
<Rows>
<Row ID="0" Name="A" />
<Row ID="1" Name="B" Desc="Some description"/>
<Row ID="3" Name="C" />
</Rows>
</TableData>
。。。将屈服
<!DOCTYPE html SYSTEM "about:legacy-compat">
<table border="1">
<tbody>
<tr>
<td><a onclick="javascript:SortColumn('Item Name')">Item Name</a></td>
<td>Item Description</td>
</tr>
<tr>
<td width="50%"><a onclick="javascript:OpenDifferentPage('A','0')">A</a></td>
<td width="50%"></td>
</tr>
<tr>
<td width="50%"><a onclick="javascript:OpenDifferentPage('B','1')">B</a></td>
<td width="50%">Some description</td>
</tr>
<tr>
<td width="50%"><a onclick="javascript:OpenDifferentPage('C','3')">C</a></td>
<td width="50%"></td>
</tr>
</tbody>
</table>