在表中重复打印xml节点
我有一个xml文件中的数据,它的一个表示是在一个n列表中,作为标签打印。我现在的方式是,每个打印标签对应于xml文件中的一个节点: xml:在表中重复打印xml节点,xml,xslt,html-table,Xml,Xslt,Html Table,我有一个xml文件中的数据,它的一个表示是在一个n列表中,作为标签打印。我现在的方式是,每个打印标签对应于xml文件中的一个节点: xml: <?xml version='1.0' encoding='UTF-8'?> <?xml-stylesheet type='text/xsl' href='table.xsl'?> <nodes> <node name="A" /> <node name="
<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='table.xsl'?>
<nodes>
<node name="A" />
<node name="A" />
<node name="A" />
<node name="B" />
<node name="B" />
<node name="B" />
<node name="B" />
<node name="C" />
<node name="C" />
</nodes>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" media-type="text/html" />
<xsl:param name="cols">3</xsl:param> <!-- set the number of columns here -->
<xsl:template match="nodes">
<table>
<tr>
<xsl:apply-templates select="node[position() mod $cols = 1 ]" mode="row"/>
</tr>
</table>
</xsl:template>
<xsl:template match="node" mode="row">
<tr>
<xsl:apply-templates select=". | following-sibling::node[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
<xsl:template match="node" mode="cell">
<td style="border: 1px dotted #999;">
<xsl:value-of select="./@name"/>
</td>
</xsl:template>
</xsl:stylesheet>
A A A
B B B
B C C
<nodes>
<node name="A" n="3"/>
<node name="B" n="4"/>
<node name="C" n="2"/>
</nodes>
为了更好的可维护性和数据完整性,我希望以这样一种方式重新定义xml,即节点不会重复,而是有自己的计数作为属性,因此:
xml:
<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='table.xsl'?>
<nodes>
<node name="A" />
<node name="A" />
<node name="A" />
<node name="B" />
<node name="B" />
<node name="B" />
<node name="B" />
<node name="C" />
<node name="C" />
</nodes>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" media-type="text/html" />
<xsl:param name="cols">3</xsl:param> <!-- set the number of columns here -->
<xsl:template match="nodes">
<table>
<tr>
<xsl:apply-templates select="node[position() mod $cols = 1 ]" mode="row"/>
</tr>
</table>
</xsl:template>
<xsl:template match="node" mode="row">
<tr>
<xsl:apply-templates select=". | following-sibling::node[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
<xsl:template match="node" mode="cell">
<td style="border: 1px dotted #999;">
<xsl:value-of select="./@name"/>
</td>
</xsl:template>
</xsl:stylesheet>
A A A
B B B
B C C
<nodes>
<node name="A" n="3"/>
<node name="B" n="4"/>
<node name="C" n="2"/>
</nodes>
我的问题是,现在position()不再与打印标签的数量对应。看起来我需要一种I=1到n的
循环。如何实现这一点?我建议您分两步完成:首先,生成所需的单个单元格;然后将它们组织到表的行中:
XSLT1.0(+EXSLT node-set())
3.
对于XSLT 3,例如使用Saxon JS 2的浏览器内部支持的实例,您可以使用
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="cols" as="xs:integer" select="3"/>
<xsl:function name="mf:repeat" as="item()*">
<xsl:param name="item" as="item()"/>
<xsl:param name="count" as="xs:integer"/>
<xsl:sequence
select="(1 to $count) ! $item"/>
</xsl:function>
<xsl:template match="/">
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>Example</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="nodes">
<table>
<tbody>
<xsl:for-each-group select="node ! mf:repeat(., @n)" group-adjacent="(position() - 1) idiv $cols">
<tr>
<xsl:apply-templates select="current-group()"/>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</xsl:template>
<xsl:template match="node">
<td>{@name}</td>
</xsl:template>
</xsl:stylesheet>
例子
例子
{@name}
声明性语言中没有循环,在XPath 2和更高版本中,您可以与XSLT 2和更高版本一起使用to
运算符来构造整数序列,例如1到xs:integer(@n)
。此外,在XSLT3中还有xsl:iterate
指令。在XSLT1中,通常需要一个命名的递归模板来跟踪“循环”索引。然而,由于您显示的数字很小,您可能只想处理//node()[position()=current()/@n]
来处理@n
节点或实现重复@n
次。这是一个优雅的解决方案,谢谢。事实上,这正是我的想法。但是恐怕我不能用更新的版本。