如何通过XSL按位置生成新标签,实现每行列序号重置?
问题:按行重置序号重命名XML的column标签
需要将以下XML转换为每行的<column>标签按行内位置命名(如column_1、column_2),且每行的序号重新计数:
<?xml version="1.0" encoding="UTF-8"?> <importoTotaleCommissioni> <row> <column>5</column> <column>6</column> </row> <row> <column>5</column> <column>6</column> <column>7</column> <column>8</column> </row> </importoTotaleCommissioni>
期望输出:
<importoTotaleCommissioni> <row> <column_1>5</column_1> <column_2>6</column_2> </row> <row> <column_1>5</column_1> <column_2>6</column_2> <column_3>7</column_3> <column_4>8</column_4> </row> </importoTotaleCommissioni>
尝试了以下XSL模板,但序号不正确:
<xsl:template match="column"> <xsl:element name="column_{position()}"> <xsl:apply-templates/> </xsl:element> </xsl:template>
请问该如何修正?
解决方案
问题出在position()的上下文:直接匹配<column>时,它的上下文是整个文档中所有<column>节点的集合,所以序号会全局递增,无法按行重置。要实现每行内重新计数,需要将<column>的处理上下文限定在所属的<row>内部。
以下是修正后的完整XSL代码:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:复制所有未专门匹配的节点和属性,保留原XML结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配row节点,限定column的处理上下文为当前行 --> <xsl:template match="row"> <xsl:copy> <xsl:apply-templates select="column"/> </xsl:copy> </xsl:template> <!-- 匹配column节点,此时position()返回行内的位置序号 --> <xsl:template match="column"> <xsl:element name="column_{position()}"> <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet>
代码说明:
- 身份模板:确保原XML中未被自定义模板匹配的节点(如根节点
<importoTotaleCommissioni>)和属性被原样复制,保证整体结构不变。 - row节点模板:显式匹配
<row>并处理其下的<column>,此时<column>的处理上下文被限定在当前<row>内部,position()会返回该列在当前行内的位置。 - column节点模板:基于行内位置生成带序号的新标签名,实现每行序号从1开始计数的需求。
内容的提问来源于stack exchange,提问作者Lore
相关产品推荐
相关产品推荐

