Xslt 将节点序列呈现为M x N表
@奥黛德:很抱歉我的演讲太差了。。。我的输入文档有如下片段:Xslt 将节点序列呈现为M x N表,xslt,Xslt,@奥黛德:很抱歉我的演讲太差了。。。我的输入文档有如下片段: <recordset name="resId" > <record n="0">example 1</record> <record n="1">example 2</record> <record n="2">example 1</record> .... <record n="N">example 1</record> &l
<recordset name="resId" >
<record n="0">example 1</record>
<record n="1">example 2</record>
<record n="2">example 1</record>
....
<record n="N">example 1</record>
</recordset>
例1
例2
例1
....
例1
包含任意长的节点序列。属性“n”报告序列中节点的顺序。我需要在一个M(行)xn(列)表中安排该序列作为输出,这样做有一些困难。我不能调用模板
<xsl:template match="recordset">
<table>
<xsl:apply-templates select="record"/>
</table>
</xsl:template>
比如:
<xsl:template match="record">
<xsl:if test="@n mod 3 = 0">
<tr>
</xsl:if>
........
<td><xsl:value-of select"something"></td>
........
因为代码无效(我应该以某种方式在模板末尾重复)
我必须对编号属性的存在给予一些信任(可能太多)。有人有提示吗?谢谢 您必须确保嵌套永不中断。要嵌套在输出中的内容必须嵌套在XSLT中
<xsl:variable name="perRow" select="3" />
<xsl:template match="recordset">
<table>
<xsl:apply-templates
mode = "tr"
select = "record[position() mod $perRow = 1]"
/>
</table>
</xsl:template>
<xsl:template match="record" mode="tr">
<tr>
<xsl:variable name="td" select="
. | following-sibling::record[position() < $perRow]
" />
<xsl:apply-templates mode="td" select="$td" />
<!-- fill up the last row -->
<xsl:if test="count($td) < $perRow">
<xsl:call-template name="filler">
<xsl:with-param name="rest" select="$perRow - count($td)" />
</xsl:call-template>
</xsl:if>
</tr>
</xsl:template>
<xsl:template match="record" mode="td">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template name="filler">
<xsl:param name="rest" select="0" />
<xsl:if test="$rest">
<td />
<xsl:call-template name="filler">
<xsl:with-param name="rest" select="$rest - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
您必须确保嵌套从未中断。要嵌套在输出中的内容必须嵌套在XSLT中
<xsl:variable name="perRow" select="3" />
<xsl:template match="recordset">
<table>
<xsl:apply-templates
mode = "tr"
select = "record[position() mod $perRow = 1]"
/>
</table>
</xsl:template>
<xsl:template match="record" mode="tr">
<tr>
<xsl:variable name="td" select="
. | following-sibling::record[position() < $perRow]
" />
<xsl:apply-templates mode="td" select="$td" />
<!-- fill up the last row -->
<xsl:if test="count($td) < $perRow">
<xsl:call-template name="filler">
<xsl:with-param name="rest" select="$perRow - count($td)" />
</xsl:call-template>
</xsl:if>
</tr>
</xsl:template>
<xsl:template match="record" mode="td">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template name="filler">
<xsl:param name="rest" select="0" />
<xsl:if test="$rest">
<td />
<xsl:call-template name="filler">
<xsl:with-param name="rest" select="$rest - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
在XSLT 1.0中,使用一般的每行n个模板 使用行元素名称作为参数,每行n个模板不会与输入或输出格式绑定
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="recordset">
<table>
<xsl:call-template name="n-per-row">
<xsl:with-param name="select" select="record" />
<xsl:with-param name="row-size" select="2"/>
<xsl:with-param name="row-element" select="'tr'"/>
</xsl:call-template>
</table>
</xsl:template>
<xsl:template match="record">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template name="n-per-row">
<xsl:param name="select" />
<xsl:param name="row-size" />
<xsl:param name="row-element" />
<xsl:param name="start">
<xsl:text>1</xsl:text>
</xsl:param>
<xsl:variable name="count" select="count($select)" />
<xsl:variable name="last-tmp" select="number($start) + number($row-size)" />
<xsl:variable name="last">
<xsl:choose>
<xsl:when test="$last-tmp > $count">
<xsl:value-of select="$count"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$last-tmp"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$row-element}">
<xsl:apply-templates select="$select[position() <= $last]"/>
</xsl:element>
<xsl:if test="count($select) > $last">
<xsl:call-template name="n-per-row">
<xsl:with-param name="select" select="$select[position() > $last]"/>
<xsl:with-param name="row-size" select="$row-size"/>
<xsl:with-param name="row-element" select="$row-element"/>
<xsl:with-param name="start" select="$start"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
1.
在XSLT 1.0中,使用一般的每行n个模板
使用行元素名称作为参数,每行n个模板不会与输入或输出格式绑定
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="recordset">
<table>
<xsl:call-template name="n-per-row">
<xsl:with-param name="select" select="record" />
<xsl:with-param name="row-size" select="2"/>
<xsl:with-param name="row-element" select="'tr'"/>
</xsl:call-template>
</table>
</xsl:template>
<xsl:template match="record">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template name="n-per-row">
<xsl:param name="select" />
<xsl:param name="row-size" />
<xsl:param name="row-element" />
<xsl:param name="start">
<xsl:text>1</xsl:text>
</xsl:param>
<xsl:variable name="count" select="count($select)" />
<xsl:variable name="last-tmp" select="number($start) + number($row-size)" />
<xsl:variable name="last">
<xsl:choose>
<xsl:when test="$last-tmp > $count">
<xsl:value-of select="$count"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$last-tmp"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$row-element}">
<xsl:apply-templates select="$select[position() <= $last]"/>
</xsl:element>
<xsl:if test="count($select) > $last">
<xsl:call-template name="n-per-row">
<xsl:with-param name="select" select="$select[position() > $last]"/>
<xsl:with-param name="row-size" select="$row-size"/>
<xsl:with-param name="row-element" select="$row-element"/>
<xsl:with-param name="start" select="$start"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
1.
使用XSLT2.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:param name="rows">3</xsl:param>
<xsl:template match="recordset">
<table>
<xsl:for-each-group select="record" group-by="count(preceding-sibling::*) mod $rows ">
<xsl:value-of select="current-grouping-key()"/>
<tr>
<xsl:for-each select="current-group()">
<td>
<xsl:apply-templates/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
3.
使用XSLT2.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:param name="rows">3</xsl:param>
<xsl:template match="recordset">
<table>
<xsl:for-each-group select="record" group-by="count(preceding-sibling::*) mod $rows ">
<xsl:value-of select="current-grouping-key()"/>
<tr>
<xsl:for-each select="current-group()">
<td>
<xsl:apply-templates/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
3.
您需要发布一些XML示例,以及一个XSL示例和所需的输出。从您的问题中不太清楚问题是什么。您需要发布一些XML示例,以及XSL示例和所需的输出。从你的问题中不太清楚问题是什么。@Lachlan:这个解决方案的递归比实际需要的要多。@Lachlan:这个解决方案的递归比实际需要的要多。很好的解决方案。我想知道它是否仍然适用于具有不同累积元素的变量,例如:而不是本例中的元素。我正试着去做,但是被卡住了。我会非常感谢你的帮助。谢谢我正在使用msxsl处理器。我一直在尝试获取$td变量中的节点列表。它选择当前节点(指定为“”),但我不知道如何正确地从$packageElements变量中指定当前节点之后的所有以下节点。@DashaLuna:这些注释中不能(或应该)回答这一问题。我认为最好单独提出一个问题,如果您愿意,可以在这里设置一个链接,并显示您的XML和XSLT,很抱歉,您是对的。我提出了一个新问题-谢谢你的建议。很好的解决方案。我想知道它是否仍然适用于具有不同累积元素的变量,例如:而不是本例中的元素。我正试着去做,但是被卡住了。我会非常感谢你的帮助。谢谢我正在使用msxsl处理器。我一直在尝试获取$td变量中的节点列表。它选择当前节点(指定为“”),但我不知道如何正确地从$packageElements变量中指定当前节点之后的所有以下节点。@DashaLuna:这些注释中不能(或应该)回答这一问题。我认为最好单独提出一个问题,如果您愿意,可以在这里设置一个链接,并显示您的XML和XSLT,很抱歉,您是对的。我提出了一个新问题——谢谢你的建议。