如何跨父元素为子元素连续编号并通过XSLT添加成绩?
跨class为person全局连续编号并添加成绩
可行,只需要修改XSLT模板,将person的编号范围从单个class扩展到整个文档的所有person节点即可。
原问题分析
你之前的XSLT模板是针对每个class内部的person位置(person[1]、person[2])添加成绩,现在需要打破class的限制,给所有person按全局顺序连续编号。
解决方案
使用xsl:number或节点计数的方式获取person的全局序号,再根据序号匹配对应成绩:
方法1:使用xsl:number(推荐,语义更清晰)
<xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="person"> <xsl:copy> <!-- 复制原person的所有属性和子节点 --> <xsl:copy-of select="@* | node()"/> <!-- 获取当前person在全局的连续序号 --> <xsl:variable name="global-rank"> <xsl:number level="any" count="person"/> </xsl:variable> <!-- 根据序号添加对应成绩 --> <grade> <xsl:choose> <xsl:when test="$global-rank = 1">A</xsl:when> <xsl:when test="$global-rank = 2">B</xsl:when> <xsl:when test="$global-rank = 3">C</xsl:when> <xsl:when test="$global-rank = 4">D</xsl:when> <!-- 可根据需要扩展更多规则 --> <xsl:otherwise>F</xsl:otherwise> </xsl:choose> </grade> </xsl:copy> </xsl:template>
方法2:使用节点计数
通过统计当前person之前所有的person节点数量,加1得到全局序号:
<xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="person"> <xsl:copy> <xsl:copy-of select="@* | node()"/> <xsl:variable name="global-rank" select="count(preceding::person) + 1"/> <grade> <xsl:choose> <xsl:when test="$global-rank = 1">A</xsl:when> <xsl:when test="$global-rank = 2">B</xsl:when> <xsl:when test="$global-rank = 3">C</xsl:when> <xsl:when test="$global-rank = 4">D</xsl:when> <xsl:otherwise>F</xsl:otherwise> </xsl:choose> </grade> </xsl:copy> </xsl:template>
效果说明
应用上述XSLT后,原XML的四个person会按全局顺序添加成绩:
- 第1个(bob)→
<grade>A</grade> - 第2个(john)→
<grade>B</grade> - 第3个(jane)→
<grade>C</grade> - 第4个(greg)→
<grade>D</grade>
内容的提问来源于stack exchange,提问作者jmwink
相关产品推荐
相关产品推荐

