如何使用XSLT统计连续符合条件的后续元素并添加MOREROWS属性
为XML表格ENTRY元素添加连续跨行的MOREROWS属性
需求说明
需要为XML表格中的ENTRY元素添加MOREROWS属性,属性值为连续后续行中,同COLNAME且CONTENT文本为##rowspan##的行数量。仅统计连续的后续行,中间出现不符合条件的行则停止计数。
解决方案(XSLT 2.0+)
通过递归函数统计连续符合条件的后续行,为符合条件的ENTRY添加属性。以下是完整的XSLT代码:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mf="http://example.com/mf"> <xsl:output method="xml" indent="yes"/> <!-- 递归函数:统计连续符合条件的后续行数量 --> <xsl:function name="mf:count-consecutive" as="xs:integer"> <xsl:param name="rows" as="element(ROW)*"/> <xsl:param name="colname" as="xs:string"/> <xsl:choose> <!-- 如果当前第一个后续行符合条件,继续统计下一行 --> <xsl:when test="$rows[1]/ENTRY[@COLNAME = $colname]/CONTENT = '##rowspan##'"> <xsl:value-of select="1 + mf:count-consecutive($rows[position() > 1], $colname)"/> </xsl:when> <!-- 不符合条件则停止,返回0 --> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:function> <!-- 复制所有节点,仅处理ENTRY元素 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理ENTRY元素,添加MOREROWS属性(仅当计数>0时) --> <xsl:template match="ENTRY"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:variable name="consecutive-count" select="mf:count-consecutive(../following-sibling::ROW, @COLNAME)"/> <xsl:if test="$consecutive-count > 0"> <xsl:attribute name="MOREROWS" select="$consecutive-count"/> </xsl:if> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码解释
递归函数
mf:count-consecutive:- 接收待检查的后续
ROW节点列表和当前ENTRY的COLNAME值两个参数 - 检查第一个后续行中对应列的
ENTRY是否符合条件,符合则递归统计下一行,否则返回0 - 确保只统计连续的符合条件的行,一旦遇到不符合的行立即停止
- 接收待检查的后续
模板匹配:
- 通用模板复制所有节点,保证原XML结构不变
- 针对
ENTRY元素的模板,调用递归函数获取连续计数,当计数大于0时添加MOREROWS属性
测试效果
将你提供的原始XML输入该XSLT转换后,会生成你期望的结果:
- 第一行
col2的ENTRY添加MOREROWS="2"(后续2行都是##rowspan##) - 第一行
col4的ENTRY添加MOREROWS="1"(仅下一行符合,再下一行不符合) - 第四行
col2和col4的ENTRY分别添加MOREROWS="1"(后续1行符合)
内容的提问来源于stack exchange,提问作者Hermund
相关产品推荐
相关产品推荐

